From: Darrick J. Wong Date: Thu, 4 Oct 2018 19:21:01 +0000 (-0500) Subject: libxfs: track transaction block reservation usage like the kernel X-Git-Tag: v4.19.0-rc0~89 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41ab92026b3ff0062f6d34169ef00ad29ff670b5;p=thirdparty%2Fxfsprogs-dev.git libxfs: track transaction block reservation usage like the kernel Currently, block reservations in userspace transactions are not carried over across transaction rolls. This will lead to ENOSPC failures inside libxfs code which checks for reservation overruns in an upcoming patch that borrows the bmbt repair code from the kernel because it makes extensive use of transaction rolling. Therefore, port t_blk_res_used from the kernel so that block reservations work the same way in userspace. [sandeen: tweaks to backport before libxfs updates] Signed-off-by: Darrick J. Wong Reviewed-by: Eric Sandeen Signed-off-by: Eric Sandeen --- diff --git a/include/xfs_trans.h b/include/xfs_trans.h index 20cf2536c..fffc99bbe 100644 --- a/include/xfs_trans.h +++ b/include/xfs_trans.h @@ -66,6 +66,7 @@ typedef struct xfs_trans { unsigned int t_log_count; /* count for perm log res */ unsigned int t_blk_res; /* # of blocks resvd */ struct xfs_mount *t_mountp; /* ptr to fs mount struct */ + unsigned int t_blk_res_used; /* # of resvd blocks used */ unsigned int t_flags; /* misc flags */ long t_icount_delta; /* superblock icount change */ long t_ifree_delta; /* superblock ifree change */ diff --git a/libxfs/trans.c b/libxfs/trans.c index 3c2253efe..e0567d504 100644 --- a/libxfs/trans.c +++ b/libxfs/trans.c @@ -155,6 +155,9 @@ xfs_trans_dup( /* We gave our writer reference to the new transaction */ tp->t_flags |= XFS_TRANS_NO_WRITECOUNT; + ntp->t_blk_res = tp->t_blk_res - tp->t_blk_res_used; + tp->t_blk_res = tp->t_blk_res_used; + ntp->t_agfl_dfops = tp->t_agfl_dfops; return ntp; @@ -778,6 +781,15 @@ libxfs_trans_mod_sb( case XFS_TRANS_SB_RES_FDBLOCKS: return; case XFS_TRANS_SB_FDBLOCKS: + if (delta < 0) { + tp->t_blk_res_used += (uint)-delta; + if (tp->t_blk_res_used > tp->t_blk_res) { + fprintf(stderr, +_("Transaction block reservation exceeded! %u > %u\n"), + tp->t_blk_res_used, tp->t_blk_res); + ASSERT(0); + } + } tp->t_fdblocks_delta += delta; break; case XFS_TRANS_SB_ICOUNT: