]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
libxfs: track transaction block reservation usage like the kernel
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 4 Oct 2018 19:21:01 +0000 (14:21 -0500)
committerEric Sandeen <sandeen@redhat.com>
Thu, 4 Oct 2018 19:21:01 +0000 (14:21 -0500)
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 <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
include/xfs_trans.h
libxfs/trans.c

index 20cf2536cdcfd3474045ce2a8b5f72fca72acd4c..fffc99bbea1cbbfc8e8d59b6e3cecd3bb9de4489 100644 (file)
@@ -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 */
index 3c2253efe0cd4f2906dbe702e72c7253c3f9e13c..e0567d504c0218612ccaa4a9c7947a9678269ca7 100644 (file)
@@ -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: