]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: move xfs_bmap_btalloc_filestreams() to xfs_filestreams.c
authorDave Chinner <dchinner@redhat.com>
Tue, 9 May 2023 09:30:44 +0000 (11:30 +0200)
committerCarlos Maiolino <cem@kernel.org>
Wed, 10 May 2023 12:59:10 +0000 (14:59 +0200)
Source kernel commit: 8f7747ad8c52cde585b9456f6dbd1984af7b97bc

xfs_bmap_btalloc_filestreams() calls two filestreams functions to
select the AG to allocate from. Both those functions end up in
the same selection function that iterates all AGs multiple times.
Worst case, xfs_bmap_btalloc_filestreams() can iterate all AGs 4
times just to select the initial AG to allocate in.

Move the AG selection to fs/xfs/xfs_filestreams.c as a single
interface so that the inefficient AG interation is contained
entirely within the filestreams code. This will allow the
implementation to be simplified and made more efficient in future
patches.

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/libxfs_priv.h
libxfs/xfs_bmap.c
libxfs/xfs_bmap.h

index 32a6be124b2f03c698ae9face9029fcdcbba6b5f..e5f37df28c0c6e27b59d8322477d85aa7350037b 100644 (file)
@@ -503,6 +503,7 @@ void __xfs_buf_mark_corrupt(struct xfs_buf *bp, xfs_failaddr_t fa);
 #define xfs_inode_is_filestream(ip)            (0)
 #define xfs_filestream_lookup_ag(ip)           (0)
 #define xfs_filestream_new_ag(ip,ag)           (0)
+#define xfs_filestream_select_ag(...)          (-ENOSYS)
 
 /* quota bits */
 #define xfs_trans_mod_dquot_byino(t,i,f,d)             ((void) 0)
index 7c5039d08d3202a4c51943330099e2a03ada8425..00836b0243849326e1125179081dbb156d5c117a 100644 (file)
@@ -3215,68 +3215,6 @@ xfs_bmap_btalloc_select_lengths(
        return error;
 }
 
-static int
-xfs_bmap_btalloc_filestreams_select_lengths(
-       struct xfs_bmalloca     *ap,
-       struct xfs_alloc_arg    *args,
-       xfs_extlen_t            *blen)
-{
-       struct xfs_mount        *mp = ap->ip->i_mount;
-       struct xfs_perag        *pag;
-       xfs_agnumber_t          start_agno;
-       int                     error;
-
-       args->total = ap->total;
-
-       start_agno = XFS_FSB_TO_AGNO(mp, ap->blkno);
-       if (start_agno == NULLAGNUMBER)
-               start_agno = 0;
-
-       pag = xfs_perag_grab(mp, start_agno);
-       if (pag) {
-               error = xfs_bmap_longest_free_extent(pag, args->tp, blen);
-               xfs_perag_rele(pag);
-               if (error) {
-                       if (error != -EAGAIN)
-                               return error;
-                       *blen = 0;
-               }
-       }
-
-       if (*blen < args->maxlen) {
-               xfs_agnumber_t  agno = start_agno;
-
-               error = xfs_filestream_new_ag(ap, &agno);
-               if (error)
-                       return error;
-               if (agno == NULLAGNUMBER)
-                       goto out_select;
-
-               pag = xfs_perag_grab(mp, agno);
-               if (!pag)
-                       goto out_select;
-
-               error = xfs_bmap_longest_free_extent(pag, args->tp, blen);
-               xfs_perag_rele(pag);
-               if (error) {
-                       if (error != -EAGAIN)
-                               return error;
-                       *blen = 0;
-               }
-               start_agno = agno;
-       }
-
-out_select:
-       args->minlen = xfs_bmap_select_minlen(ap, args, *blen);
-
-       /*
-        * Set the failure fallback case to look in the selected AG as stream
-        * may have moved.
-        */
-       ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, start_agno, 0);
-       return 0;
-}
-
 /* Update all inode and quota accounting for the allocation we just did. */
 static void
 xfs_bmap_btalloc_accounting(
@@ -3570,7 +3508,7 @@ xfs_bmap_btalloc_at_eof(
  * transaction that we are critically low on space so they don't waste time on
  * allocation modes that are unlikely to succeed.
  */
-static int
+int
 xfs_bmap_btalloc_low_space(
        struct xfs_bmalloca     *ap,
        struct xfs_alloc_arg    *args)
@@ -3599,36 +3537,25 @@ xfs_bmap_btalloc_filestreams(
        struct xfs_alloc_arg    *args,
        int                     stripe_align)
 {
-       xfs_agnumber_t          agno = xfs_filestream_lookup_ag(ap->ip);
        xfs_extlen_t            blen = 0;
        int                     error;
 
-       /* 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);
+
+       error = xfs_filestream_select_ag(ap, args, &blen);
+       if (error)
+               return error;
 
        /*
-        * 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 we are in low space mode, then optimal allocation will fail so
+        * prepare for minimal allocation and jump to the low space algorithm
+        * immediately.
         */
        if (ap->tp->t_flags & XFS_TRANS_LOWMODE) {
                args->minlen = ap->minlen;
-               return xfs_bmap_btalloc_low_space(ap, args);
+               goto out_low_space;
        }
 
-       /*
-        * 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_filestreams_select_lengths(ap, args, &blen);
-       if (error)
-               return error;
-
+       args->minlen = xfs_bmap_select_minlen(ap, args, blen);
        if (ap->aeof) {
                error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align,
                                true);
@@ -3640,6 +3567,7 @@ xfs_bmap_btalloc_filestreams(
        if (error || args->fsbno != NULLFSBLOCK)
                return error;
 
+out_low_space:
        return xfs_bmap_btalloc_low_space(ap, args);
 }
 
index b52cfdcb932062660589fa4966c15bbb595cbaff..dd08361ca5a6998981991ec53d85926395bb598a 100644 (file)
@@ -12,6 +12,7 @@ struct xfs_ifork;
 struct xfs_inode;
 struct xfs_mount;
 struct xfs_trans;
+struct xfs_alloc_arg;
 
 /*
  * Argument structure for xfs_bmap_alloc.
@@ -224,6 +225,8 @@ int xfs_bmap_add_extent_unwritten_real(struct xfs_trans *tp,
                struct xfs_bmbt_irec *new, int *logflagsp);
 xfs_extlen_t xfs_bmapi_minleft(struct xfs_trans *tp, struct xfs_inode *ip,
                int fork);
+int    xfs_bmap_btalloc_low_space(struct xfs_bmalloca *ap,
+               struct xfs_alloc_arg *args);
 
 enum xfs_bmap_intent_type {
        XFS_BMAP_MAP = 1,