diff options
author | Darrick J. Wong <djwong@kernel.org> | 2021-09-01 10:46:52 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-12-15 17:28:57 -0800 |
commit | d0099433da606bbcba9007facc98f4340dd8a521 (patch) | |
tree | 9fe104ecdd9066d67a1329ad8d2309172ce10ab8 /fs/xfs | |
parent | 07ed94387e8cf12768b9c810e1c4dff34ce7c63d (diff) |
xfs: fix xfs_bunmapi to allow unmapping of partial rt extents
When XFS_BMAPI_REMAP is passed to bunmapi, that means that we want to
remove part of a block mapping without touching the allocator. For
realtime files with rtextsize > 1, that also means that we should skip
all the code that changes a partial remove request into an unwritten
extent conversion. IOWs, bunmapi in this mode should handle removing
the mapping from the rt file and nothing else.
Note that XFS_BMAPI_REMAP callers are required to decrement the
reference count and/or free the space manually.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 89380ad9da2d..5bacc4380330 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5115,15 +5115,14 @@ xfs_bmap_del_extent_real( flags = XFS_ILOG_CORE; if (xfs_ifork_is_realtime(ip, whichfork)) { - xfs_filblks_t len; - xfs_extlen_t mod; - - len = div_u64_rem(del->br_blockcount, mp->m_sb.sb_rextsize, - &mod); - ASSERT(mod == 0); - if (!(bflags & XFS_BMAPI_REMAP)) { xfs_fsblock_t bno; + xfs_filblks_t len; + xfs_extlen_t mod; + + len = div_u64_rem(del->br_blockcount, + mp->m_sb.sb_rextsize, &mod); + ASSERT(mod == 0); bno = div_u64_rem(del->br_startblock, mp->m_sb.sb_rextsize, &mod); @@ -5132,10 +5131,12 @@ xfs_bmap_del_extent_real( error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len); if (error) goto done; + nblks = len * mp->m_sb.sb_rextsize; + } else { + nblks = del->br_blockcount; } do_fx = 0; - nblks = len * mp->m_sb.sb_rextsize; qfield = XFS_TRANS_DQ_RTBCOUNT; } else { do_fx = 1; @@ -5462,7 +5463,7 @@ __xfs_bunmapi( if (del.br_startoff + del.br_blockcount > end + 1) del.br_blockcount = end + 1 - del.br_startoff; - if (!isrt) + if (!isrt || (flags & XFS_BMAPI_REMAP)) goto delete; sum = del.br_startblock + del.br_blockcount; @@ -5480,7 +5481,7 @@ __xfs_bunmapi( * This piece is unwritten, or we're not * using unwritten extents. Skip over it. */ - ASSERT(end >= mod); + ASSERT((flags & XFS_BMAPI_REMAP) || end >= mod); end -= mod > del.br_blockcount ? del.br_blockcount : mod; if (end < got.br_startoff && |