summaryrefslogtreecommitdiff
path: root/fs/xfs
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-09-01 10:46:52 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-12-15 17:28:57 -0800
commitd0099433da606bbcba9007facc98f4340dd8a521 (patch)
tree9fe104ecdd9066d67a1329ad8d2309172ce10ab8 /fs/xfs
parent07ed94387e8cf12768b9c810e1c4dff34ce7c63d (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.c21
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 &&