Add a new function xfs_bmap_split_da_extent to split a delalloc extent into two delalloc extents. Signed-off-by: yu kuai <yukuai3@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_bmap.c | 26 ++++++++++++++++++++++++-- fs/xfs/libxfs/xfs_bmap.h | 1 + 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 4c2e046fbfad..8247054c1e2b 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -6117,7 +6117,7 @@ xfs_bmap_split_extent_at( /* * Convert to a btree if necessary. */ - if (xfs_bmap_needs_btree(ip, whichfork)) { + if (tp && xfs_bmap_needs_btree(ip, whichfork)) { int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); @@ -6132,7 +6132,7 @@ xfs_bmap_split_extent_at( xfs_btree_del_cursor(cur, error); } - if (logflags) + if (tp && logflags) xfs_trans_log_inode(tp, ip, logflags); return error; } @@ -6165,6 +6165,28 @@ xfs_bmap_split_extent( return error; } +/* + * Splits a delalloc extent into two delalloc extents at split_fsb block + * such that it is the first block of the current_ext. Caller has to make + * sure split_fsb belong to a delalloc extent. + * If split_fsb is not the first block of the extent, caller need to sub + * the @ip->i_d.di_nextents to prevent crash in log recovery. + */ +int +xfs_bmap_split_da_extent( + struct xfs_inode *ip, + xfs_fileoff_t split_fsb) +{ + struct xfs_trans *tp = NULL; + int error; + + xfs_ilock(ip, XFS_ILOCK_EXCL); + error = xfs_bmap_split_extent_at(tp, ip, split_fsb); + xfs_iunlock(ip, XFS_ILOCK_EXCL); + + return error; +} + /* Deferred mapping is only for real extents in the data fork. */ static bool xfs_bmap_is_update_needed( diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 14d25e0b7d9c..d8d969aa17ef 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -223,6 +223,7 @@ int xfs_bmap_insert_extents(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, bool *done, xfs_fileoff_t stop_fsb); int xfs_bmap_split_extent(struct xfs_inode *ip, xfs_fileoff_t split_offset); +int xfs_bmap_split_da_extent(struct xfs_inode *ip, xfs_fileoff_t split_offset); int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork, xfs_fileoff_t off, xfs_filblks_t len, xfs_filblks_t prealloc, struct xfs_bmbt_irec *got, struct xfs_iext_cursor *cur, -- 2.17.2