]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: factor out filestreams from xfs_bmap_btalloc_nullfb
authorDave Chinner <dchinner@redhat.com>
Tue, 9 May 2023 09:30:39 +0000 (11:30 +0200)
committerCarlos Maiolino <cem@kernel.org>
Wed, 10 May 2023 12:44:58 +0000 (14:44 +0200)
Source kernel commit: 89563e7dc099343bf7792515452e1a24005d98a6

There's many if (filestreams) {} else {} branches in this function.
Split it out into a filestreams specific function so that we can
then work directly on cleaning up the filestreams code without
impacting the rest of the allocation algorithms.

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_bmap.c

index 9a1e0e33e77260444e094620fe6dc63d29948c1f..e788e33e5df9c3de2843ae2d63c6591f5ee0dcc2 100644 (file)
@@ -3227,8 +3227,8 @@ xfs_bmap_btalloc_select_lengths(
        return error;
 }
 
-STATIC int
-xfs_bmap_btalloc_filestreams(
+static int
+xfs_bmap_btalloc_filestreams_select_lengths(
        struct xfs_bmalloca     *ap,
        struct xfs_alloc_arg    *args,
        xfs_extlen_t            *blen)
@@ -3569,54 +3569,109 @@ xfs_bmap_btalloc_at_eof(
        return 0;
 }
 
+/*
+ * We have failed multiple allocation attempts so now are in a low space
+ * allocation situation. Try a locality first full filesystem minimum length
+ * allocation whilst still maintaining necessary total block reservation
+ * requirements.
+ *
+ * If that fails, we are now critically low on space, so perform a last resort
+ * allocation attempt: no reserve, no locality, blocking, minimum length, full
+ * filesystem free space scan. We also indicate to future allocations in this
+ * transaction that we are critically low on space so they don't waste time on
+ * allocation modes that are unlikely to succeed.
+ */
 static int
-xfs_bmap_btalloc_best_length(
+xfs_bmap_btalloc_low_space(
+       struct xfs_bmalloca     *ap,
+       struct xfs_alloc_arg    *args)
+{
+       int                     error;
+
+       if (args->minlen > ap->minlen) {
+               args->minlen = ap->minlen;
+               error = xfs_alloc_vextent_start_ag(args, ap->blkno);
+               if (error || args->fsbno != NULLFSBLOCK)
+                       return error;
+       }
+
+       /* Last ditch attempt before failure is declared. */
+       args->total = ap->minlen;
+       error = xfs_alloc_vextent_first_ag(args, 0);
+       if (error)
+               return error;
+       ap->tp->t_flags |= XFS_TRANS_LOWMODE;
+       return 0;
+}
+
+static int
+xfs_bmap_btalloc_filestreams(
        struct xfs_bmalloca     *ap,
        struct xfs_alloc_arg    *args,
        int                     stripe_align)
 {
-       struct xfs_mount        *mp = args->mp;
+       xfs_agnumber_t          agno = xfs_filestream_lookup_ag(ap->ip);
        xfs_extlen_t            blen = 0;
-       bool                    is_filestream = false;
        int                     error;
 
-       if ((ap->datatype & XFS_ALLOC_USERDATA) &&
-           xfs_inode_is_filestream(ap->ip))
-               is_filestream = true;
+       /* Determine the initial block number we will target for allocation. */
+       if (agno == NULLAGNUMBER)
+               agno = 0;
+       ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0);
+       xfs_bmap_adjacent(ap);
 
        /*
-        * Determine the initial block number we will target for allocation.
+        * If there is very little free space before we start a
+        * filestreams allocation, we're almost guaranteed to fail to
+        * find an AG with enough contiguous free space to succeed, so
+        * just go straight to the low space algorithm.
         */
-       if (is_filestream) {
-               xfs_agnumber_t  agno = xfs_filestream_lookup_ag(ap->ip);
-               if (agno == NULLAGNUMBER)
-                       agno = 0;
-               ap->blkno = XFS_AGB_TO_FSB(mp, agno, 0);
-       } else {
-               ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
+       if (ap->tp->t_flags & XFS_TRANS_LOWMODE) {
+               args->minlen = ap->minlen;
+               return xfs_bmap_btalloc_low_space(ap, args);
        }
-       xfs_bmap_adjacent(ap);
 
        /*
         * Search for an allocation group with a single extent large enough for
         * the request.  If one isn't found, then adjust the minimum allocation
         * size to the largest space found.
         */
-       if (is_filestream) {
-               /*
-                * If there is very little free space before we start a
-                * filestreams allocation, we're almost guaranteed to fail to
-                * find an AG with enough contiguous free space to succeed, so
-                * just go straight to the low space algorithm.
-                */
-               if (ap->tp->t_flags & XFS_TRANS_LOWMODE) {
-                       args->minlen = ap->minlen;
-                       goto critically_low_space;
-               }
-               error = xfs_bmap_btalloc_filestreams(ap, args, &blen);
-       } else {
-               error = xfs_bmap_btalloc_select_lengths(ap, args, &blen);
+       error = xfs_bmap_btalloc_filestreams_select_lengths(ap, args, &blen);
+       if (error)
+               return error;
+
+       if (ap->aeof) {
+               error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align,
+                               true);
+               if (error || args->fsbno != NULLFSBLOCK)
+                       return error;
        }
+
+       error = xfs_alloc_vextent_near_bno(args, ap->blkno);
+       if (error || args->fsbno != NULLFSBLOCK)
+               return error;
+
+       return xfs_bmap_btalloc_low_space(ap, args);
+}
+
+static int
+xfs_bmap_btalloc_best_length(
+       struct xfs_bmalloca     *ap,
+       struct xfs_alloc_arg    *args,
+       int                     stripe_align)
+{
+       xfs_extlen_t            blen = 0;
+       int                     error;
+
+       ap->blkno = XFS_INO_TO_FSB(args->mp, ap->ip->i_ino);
+       xfs_bmap_adjacent(ap);
+
+       /*
+        * Search for an allocation group with a single extent large enough for
+        * the request.  If one isn't found, then adjust the minimum allocation
+        * size to the largest space found.
+        */
+       error = xfs_bmap_btalloc_select_lengths(ap, args, &blen);
        if (error)
                return error;
 
@@ -3628,50 +3683,16 @@ xfs_bmap_btalloc_best_length(
         */
        if (ap->aeof && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) {
                error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align,
-                               is_filestream);
-               if (error)
+                               false);
+               if (error || args->fsbno != NULLFSBLOCK)
                        return error;
-               if (args->fsbno != NULLFSBLOCK)
-                       return 0;
        }
 
-       if (is_filestream)
-               error = xfs_alloc_vextent_near_bno(args, ap->blkno);
-       else
-               error = xfs_alloc_vextent_start_ag(args, ap->blkno);
-       if (error)
+       error = xfs_alloc_vextent_start_ag(args, ap->blkno);
+       if (error || args->fsbno != NULLFSBLOCK)
                return error;
-       if (args->fsbno != NULLFSBLOCK)
-               return 0;
-
-       /*
-        * Try a locality first full filesystem minimum length allocation whilst
-        * still maintaining necessary total block reservation requirements.
-        */
-       if (args->minlen > ap->minlen) {
-               args->minlen = ap->minlen;
-               error = xfs_alloc_vextent_start_ag(args, ap->blkno);
-               if (error)
-                       return error;
-       }
-       if (args->fsbno != NULLFSBLOCK)
-               return 0;
 
-       /*
-        * We are now critically low on space, so this is a last resort
-        * allocation attempt: no reserve, no locality, blocking, minimum
-        * length, full filesystem free space scan. We also indicate to future
-        * allocations in this transaction that we are critically low on space
-        * so they don't waste time on allocation modes that are unlikely to
-        * succeed.
-        */
-critically_low_space:
-       args->total = ap->minlen;
-       error = xfs_alloc_vextent_first_ag(args, 0);
-       if (error)
-               return error;
-       ap->tp->t_flags |= XFS_TRANS_LOWMODE;
-       return 0;
+       return xfs_bmap_btalloc_low_space(ap, args);
 }
 
 static int
@@ -3705,7 +3726,11 @@ xfs_bmap_btalloc(
        /* Trim the allocation back to the maximum an AG can fit. */
        args.maxlen = min(ap->length, mp->m_ag_max_usable);
 
-       error = xfs_bmap_btalloc_best_length(ap, &args, stripe_align);
+       if ((ap->datatype & XFS_ALLOC_USERDATA) &&
+           xfs_inode_is_filestream(ap->ip))
+               error = xfs_bmap_btalloc_filestreams(ap, &args, stripe_align);
+       else
+               error = xfs_bmap_btalloc_best_length(ap, &args, stripe_align);
        if (error)
                return error;