xfs: don't set bmapi total block req where minleft is
authorBrian Foster <bfoster@redhat.com>
Mon, 21 Oct 2019 16:26:48 +0000 (09:26 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Thu, 24 Oct 2019 00:01:08 +0000 (17:01 -0700)
xfs_bmapi_write() takes a total block requirement parameter that is
passed down to the block allocation code and is used to specify the
total block requirement of the associated transaction. This is used
to try and select an AG that can not only satisfy the requested
extent allocation, but can also accommodate subsequent allocations
that might be required to complete the transaction. For example,
additional bmbt block allocations may be required on insertion of
the resulting extent to an inode data fork.

While it's important for callers to calculate and reserve such extra
blocks in the transaction, it is not necessary to pass the total
value to xfs_bmapi_write() in all cases. The latter automatically
sets minleft to ensure that sufficient free blocks remain after the
allocation attempt to expand the format of the associated inode
(i.e., such as extent to btree conversion, btree splits, etc).
Therefore, any callers that pass a total block requirement of the
bmap mapping length plus worst case bmbt expansion essentially
specify the additional reservation requirement twice. These callers
can pass a total of zero to rely on the bmapi minleft policy.

Beyond being superfluous, the primary motivation for this change is
that the total reservation logic in the bmbt code is dubious in
scenarios where minlen < maxlen and a maxlen extent cannot be
allocated (which is more common for data extent allocations where
contiguity is not required). The total value is based on maxlen in
the xfs_bmapi_write() caller. If the bmbt code falls back to an
allocation between minlen and maxlen, that allocation will not
succeed until total is reset to minlen, which essentially throws
away any additional reservation included in total by the caller. In
addition, the total value is not reset until after alignment is
dropped, which means that such callers drop alignment far too
aggressively than necessary.

Update all callers of xfs_bmapi_write() that pass a total block
value of the mapping length plus bmbt reservation to instead pass
zero and rely on xfs_bmapi_minleft() to enforce the bmbt reservation
requirement. This trades off slightly less conservative AG selection
for the ability to preserve alignment in more scenarios.
xfs_bmapi_write() callers that incorporate unrelated or additional
reservations in total beyond what is already included in minleft
must continue to use the former.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_dquot.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_reflink.c
fs/xfs/xfs_rtalloc.c

index 3b300b518f69303155ff6b1ec3b8feb0ef50b13a..392a809c13e809782029013d70609f7d833fcf80 100644 (file)
@@ -4511,7 +4511,6 @@ xfs_bmapi_convert_delalloc(
        bma.wasdel = true;
        bma.offset = bma.got.br_startoff;
        bma.length = max_t(xfs_filblks_t, bma.got.br_blockcount, MAXEXTLEN);
-       bma.total = XFS_EXTENTADD_SPACE_RES(ip->i_mount, XFS_DATA_FORK);
        bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork);
        if (whichfork == XFS_COW_FORK)
                bma.flags = XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC;
index 5d8632b7f5493c691c857f8b0905b40be3c0e800..99bf372ed551c75dc37601072869d1d5f1b9240e 100644 (file)
@@ -964,8 +964,8 @@ xfs_alloc_file_space(
                xfs_trans_ijoin(tp, ip, 0);
 
                error = xfs_bmapi_write(tp, ip, startoffset_fsb,
-                                       allocatesize_fsb, alloc_type, resblks,
-                                       imapp, &nimaps);
+                                       allocatesize_fsb, alloc_type, 0, imapp,
+                                       &nimaps);
                if (error)
                        goto error0;
 
index aeb95e7391c179a284ae606b293458ca66cec8dc..b924dbd63a7d56cb4bd97e95de1c15056a19d6c2 100644 (file)
@@ -305,8 +305,8 @@ xfs_dquot_disk_alloc(
        /* Create the block mapping. */
        xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL);
        error = xfs_bmapi_write(tp, quotip, dqp->q_fileoffset,
-                       XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA,
-                       XFS_QM_DQALLOC_SPACE_RES(mp), &map, &nmaps);
+                       XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, 0, &map,
+                       &nmaps);
        if (error)
                return error;
        ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
index bf0c7756ac90403b76c0c780d59a782a91c068d0..e8fb500e1880deebe6940d546b2da8b468714ed6 100644 (file)
@@ -285,8 +285,8 @@ xfs_iomap_write_direct(
         * caller gave to us.
         */
        nimaps = 1;
-       error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb,
-                               bmapi_flags, resblks, imap, &nimaps);
+       error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, bmapi_flags, 0,
+                               imap, &nimaps);
        if (error)
                goto out_res_cancel;
 
index 1e18b4024b820daf32f369c437cd6d21c19cfe4d..de451235c4ee3aa64004bf660d926f18fe5dc83a 100644 (file)
@@ -410,8 +410,8 @@ xfs_reflink_allocate_cow(
        /* Allocate the entire reservation as unwritten blocks. */
        nimaps = 1;
        error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount,
-                       XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC,
-                       resblks, cmap, &nimaps);
+                       XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, 0, cmap,
+                       &nimaps);
        if (error)
                goto out_unreserve;
 
index 4a48a8c75b4f75a98d2a2c858a00d657195ca75f..d42b5a2047e03bfcb902f284e06cbc97b69f7b84 100644 (file)
@@ -792,8 +792,7 @@ xfs_growfs_rt_alloc(
                 */
                nmap = 1;
                error = xfs_bmapi_write(tp, ip, oblocks, nblocks - oblocks,
-                                       XFS_BMAPI_METADATA, resblks, &map,
-                                       &nmap);
+                                       XFS_BMAPI_METADATA, 0, &map, &nmap);
                if (!error && nmap < 1)
                        error = -ENOSPC;
                if (error)