]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: introduce xfs_alloc_vextent_near_bno()
authorDave Chinner <dchinner@redhat.com>
Tue, 9 May 2023 09:30:25 +0000 (11:30 +0200)
committerCarlos Maiolino <cem@kernel.org>
Wed, 10 May 2023 12:14:31 +0000 (14:14 +0200)
Source kernel commit: db4710fd12248e5d4c3842520cd13f034136576b

The remaining callers of xfs_alloc_vextent() are all doing NEAR_BNO
allocations. We can replace that function with a new
xfs_alloc_vextent_near_bno() function that does this explicitly.

We also multiplex NEAR_BNO allocations through
xfs_alloc_vextent_this_ag via args->type. Replace all of these with
direct calls to xfs_alloc_vextent_near_bno(), too.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
libxfs/xfs_alloc.c
libxfs/xfs_alloc.h
libxfs/xfs_bmap.c
libxfs/xfs_ialloc.c
libxfs/xfs_ialloc_btree.c
libxfs/xfs_refcount_btree.c

index 798d7a5be23c922cb3154066db51965efbac1fc5..797d1a2aa81b921760f9a42fe04d6e17f6b7f995 100644 (file)
@@ -3475,35 +3475,47 @@ xfs_alloc_vextent_first_ag(
 }
 
 /*
- * Allocate an extent (variable-size).
- * Depending on the allocation type, we either look in a single allocation
- * group or loop over the allocation groups to find the result.
+ * Allocate an extent as close to the target as possible. If there are not
+ * viable candidates in the AG, then fail the allocation.
  */
 int
-xfs_alloc_vextent(
-       struct xfs_alloc_arg    *args)
+xfs_alloc_vextent_near_bno(
+       struct xfs_alloc_arg    *args,
+       xfs_fsblock_t           target)
 {
+       struct xfs_mount        *mp = args->mp;
+       bool                    need_pag = !args->pag;
        xfs_agnumber_t          minimum_agno = 0;
        int                     error;
 
        if (args->tp->t_highest_agno != NULLAGNUMBER)
                minimum_agno = args->tp->t_highest_agno;
 
-       switch (args->type) {
-       case XFS_ALLOCTYPE_THIS_AG:
-       case XFS_ALLOCTYPE_NEAR_BNO:
-       case XFS_ALLOCTYPE_THIS_BNO:
-               args->pag = xfs_perag_get(args->mp,
-                               XFS_FSB_TO_AGNO(args->mp, args->fsbno));
-               error = xfs_alloc_vextent_this_ag(args);
-               xfs_perag_put(args->pag);
-               break;
-       default:
-               error = -EFSCORRUPTED;
-               ASSERT(0);
-               break;
+       error = xfs_alloc_vextent_check_args(args, target);
+       if (error) {
+               if (error == -ENOSPC)
+                       return 0;
+               return error;
        }
-       return error;
+
+       args->agno = XFS_FSB_TO_AGNO(mp, target);
+       if (minimum_agno > args->agno) {
+               trace_xfs_alloc_vextent_skip_deadlock(args);
+               return 0;
+       }
+
+       args->agbno = XFS_FSB_TO_AGBNO(mp, target);
+       args->type = XFS_ALLOCTYPE_NEAR_BNO;
+       if (need_pag)
+               args->pag = xfs_perag_get(args->mp, args->agno);
+       error = xfs_alloc_ag_vextent(args);
+       if (need_pag)
+               xfs_perag_put(args->pag);
+       if (error)
+               return error;
+
+       xfs_alloc_vextent_set_fsbno(args, minimum_agno);
+       return 0;
 }
 
 /* Ensure that the freelist is at full capacity. */
index 80e2c16f4cde7c306ea0411a9658fdbbc5696872..45a428e770f0713a92f686da1f3d114aaeb1de42 100644 (file)
@@ -113,19 +113,19 @@ xfs_alloc_log_agf(
        struct xfs_buf  *bp,    /* buffer for a.g. freelist header */
        uint32_t        fields);/* mask of fields to be logged (XFS_AGF_...) */
 
-/*
- * Allocate an extent (variable-size).
- */
-int                            /* error */
-xfs_alloc_vextent(
-       xfs_alloc_arg_t *args); /* allocation argument structure */
-
 /*
  * Allocate an extent in the specific AG defined by args->fsbno. If there is no
  * space in that AG, then the allocation will fail.
  */
 int xfs_alloc_vextent_this_ag(struct xfs_alloc_arg *args);
 
+/*
+ * Allocate an extent as close to the target as possible. If there are not
+ * viable candidates in the AG, then fail the allocation.
+ */
+int xfs_alloc_vextent_near_bno(struct xfs_alloc_arg *args,
+               xfs_fsblock_t target);
+
 /*
  * Best effort full filesystem allocation scan.
  *
index 31b65f88f59d3c78744176eb6f67799064b0b2ea..ea52414256cec982c2ef9f288e7eb7e8f00d5c6d 100644 (file)
@@ -3239,7 +3239,6 @@ xfs_bmap_btalloc_filestreams(
        int                     notinit = 0;
        int                     error;
 
-       args->type = XFS_ALLOCTYPE_NEAR_BNO;
        args->total = ap->total;
 
        start_agno = XFS_FSB_TO_AGNO(mp, ap->blkno);
@@ -3558,7 +3557,7 @@ xfs_bmap_btalloc_at_eof(
        }
 
        if (ag_only)
-               error = xfs_alloc_vextent(args);
+               error = xfs_alloc_vextent_near_bno(args, ap->blkno);
        else
                error = xfs_alloc_vextent_start_ag(args, ap->blkno);
        if (error)
@@ -3605,7 +3604,6 @@ xfs_bmap_btalloc_best_length(
                ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
        }
        xfs_bmap_adjacent(ap);
-       args->fsbno = ap->blkno;
 
        /*
         * Search for an allocation group with a single extent large enough for
@@ -3646,7 +3644,7 @@ xfs_bmap_btalloc_best_length(
        }
 
        if (is_filestream)
-               error = xfs_alloc_vextent(args);
+               error = xfs_alloc_vextent_near_bno(args, ap->blkno);
        else
                error = xfs_alloc_vextent_start_ag(args, ap->blkno);
        if (error)
index c9a47296b98e2e55dc1a7f75799997d7f487b3d7..77ea0ce26145f900995cf1d7413c666b9ba465d4 100644 (file)
@@ -712,23 +712,17 @@ xfs_ialloc_ag_alloc(
                        isaligned = 1;
                } else
                        args.alignment = igeo->cluster_align;
-               /*
-                * Need to figure out where to allocate the inode blocks.
-                * Ideally they should be spaced out through the a.g.
-                * For now, just allocate blocks up front.
-                */
-               args.agbno = be32_to_cpu(agi->agi_root);
-               args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno);
                /*
                 * Allocate a fixed-size extent of inodes.
                 */
-               args.type = XFS_ALLOCTYPE_NEAR_BNO;
                args.prod = 1;
                /*
                 * Allow space for the inode btree to split.
                 */
                args.minleft = igeo->inobt_maxlevels;
-               error = xfs_alloc_vextent_this_ag(&args);
+               error = xfs_alloc_vextent_near_bno(&args,
+                               XFS_AGB_TO_FSB(args.mp, pag->pag_agno,
+                                               be32_to_cpu(agi->agi_root)));
                if (error)
                        return error;
        }
@@ -738,11 +732,11 @@ xfs_ialloc_ag_alloc(
         * alignment.
         */
        if (isaligned && args.fsbno == NULLFSBLOCK) {
-               args.type = XFS_ALLOCTYPE_NEAR_BNO;
-               args.agbno = be32_to_cpu(agi->agi_root);
-               args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno);
                args.alignment = igeo->cluster_align;
-               if ((error = xfs_alloc_vextent(&args)))
+               error = xfs_alloc_vextent_near_bno(&args,
+                               XFS_AGB_TO_FSB(args.mp, pag->pag_agno,
+                                               be32_to_cpu(agi->agi_root)));
+               if (error)
                        return error;
        }
 
@@ -754,9 +748,6 @@ xfs_ialloc_ag_alloc(
            igeo->ialloc_min_blks < igeo->ialloc_blks &&
            args.fsbno == NULLFSBLOCK) {
 sparse_alloc:
-               args.type = XFS_ALLOCTYPE_NEAR_BNO;
-               args.agbno = be32_to_cpu(agi->agi_root);
-               args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno);
                args.alignment = args.mp->m_sb.sb_spino_align;
                args.prod = 1;
 
@@ -778,7 +769,9 @@ sparse_alloc:
                                            args.mp->m_sb.sb_inoalignmt) -
                                 igeo->ialloc_blks;
 
-               error = xfs_alloc_vextent_this_ag(&args);
+               error = xfs_alloc_vextent_near_bno(&args,
+                               XFS_AGB_TO_FSB(args.mp, pag->pag_agno,
+                                               be32_to_cpu(agi->agi_root)));
                if (error)
                        return error;
 
index e10c1f078e055ec71b1e0e10bcad2f03d6b5f2a2..2f3d1e8d043d2001f585e2fea8235e375d076ade 100644 (file)
@@ -104,14 +104,13 @@ __xfs_inobt_alloc_block(
        args.mp = cur->bc_mp;
        args.pag = cur->bc_ag.pag;
        args.oinfo = XFS_RMAP_OINFO_INOBT;
-       args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_ag.pag->pag_agno, sbno);
        args.minlen = 1;
        args.maxlen = 1;
        args.prod = 1;
-       args.type = XFS_ALLOCTYPE_NEAR_BNO;
        args.resv = resv;
 
-       error = xfs_alloc_vextent_this_ag(&args);
+       error = xfs_alloc_vextent_near_bno(&args,
+                       XFS_AGB_TO_FSB(args.mp, args.pag->pag_agno, sbno));
        if (error)
                return error;
 
index 970ff2dafbdaaa26b3ae0326d7970489d4533557..2fbf2e2a72f3600fb9a449e9e22f70490bc7ffb6 100644 (file)
@@ -67,14 +67,13 @@ xfs_refcountbt_alloc_block(
        args.tp = cur->bc_tp;
        args.mp = cur->bc_mp;
        args.pag = cur->bc_ag.pag;
-       args.type = XFS_ALLOCTYPE_NEAR_BNO;
-       args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.pag->pag_agno,
-                       xfs_refc_block(args.mp));
        args.oinfo = XFS_RMAP_OINFO_REFC;
        args.minlen = args.maxlen = args.prod = 1;
        args.resv = XFS_AG_RESV_METADATA;
 
-       error = xfs_alloc_vextent_this_ag(&args);
+       error = xfs_alloc_vextent_near_bno(&args,
+                       XFS_AGB_TO_FSB(args.mp, args.pag->pag_agno,
+                                       xfs_refc_block(args.mp)));
        if (error)
                goto out_error;
        trace_xfs_refcountbt_alloc_block(cur->bc_mp, cur->bc_ag.pag->pag_agno,