]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: split up xfs_buf_alloc_backing_mem
authorChristoph Hellwig <hch@lst.de>
Wed, 17 Jun 2026 05:58:02 +0000 (07:58 +0200)
committerCarlos Maiolino <cem@kernel.org>
Mon, 29 Jun 2026 07:37:05 +0000 (09:37 +0200)
Split out helpers for folio and vmalloc allocations to prepare for a bug
fix.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
fs/xfs/xfs_buf.c

index 3ce12fe1c3078492bce7bace85498589520a3235..d1b7729559f00a6f2ebe47650317ba84cd326514 100644 (file)
@@ -120,6 +120,22 @@ xfs_buf_free(
        call_rcu(&bp->b_rcu, xfs_buf_free_callback);
 }
 
+static int
+xfs_buf_alloc_folio(
+       struct xfs_buf          *bp,
+       size_t                  size,
+       gfp_t                   gfp_mask)
+{
+       struct folio            *folio;
+
+       folio = folio_alloc(gfp_mask, get_order(size));
+       if (!folio)
+               return -ENOMEM;
+       bp->b_addr = folio_address(folio);
+       trace_xfs_buf_backing_folio(bp, _RET_IP_);
+       return 0;
+}
+
 static int
 xfs_buf_alloc_kmem(
        struct xfs_buf          *bp,
@@ -148,6 +164,27 @@ xfs_buf_alloc_kmem(
        return 0;
 }
 
+static int
+xfs_buf_alloc_vmalloc(
+       struct xfs_buf          *bp,
+       size_t                  size,
+       gfp_t                   gfp_mask,
+       xfs_buf_flags_t         flags)
+{
+       for (;;) {
+               bp->b_addr = __vmalloc(size, gfp_mask);
+               if (bp->b_addr)
+                       break;
+               if (flags & XBF_READ_AHEAD)
+                       return -ENOMEM;
+               XFS_STATS_INC(bp->b_mount, xb_page_retries);
+               memalloc_retry_wait(gfp_mask);
+       }
+
+       trace_xfs_buf_backing_vmalloc(bp, _RET_IP_);
+       return 0;
+}
+
 /*
  * Allocate backing memory for a buffer.
  *
@@ -175,7 +212,6 @@ xfs_buf_alloc_backing_mem(
 {
        size_t          size = BBTOB(bp->b_length);
        gfp_t           gfp_mask = GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOWARN;
-       struct folio    *folio;
 
        if (xfs_buftarg_is_mem(bp->b_target))
                return xmbuf_map_backing_mem(bp);
@@ -216,33 +252,16 @@ xfs_buf_alloc_backing_mem(
         */
        if (size > PAGE_SIZE) {
                if (!is_power_of_2(size))
-                       goto fallback;
+                       return xfs_buf_alloc_vmalloc(bp, size, gfp_mask, flags);
                gfp_mask &= ~__GFP_DIRECT_RECLAIM;
                gfp_mask |= __GFP_NORETRY;
        }
-       folio = folio_alloc(gfp_mask, get_order(size));
-       if (!folio) {
+       if (xfs_buf_alloc_folio(bp, size, gfp_mask) < 0) {
                if (size <= PAGE_SIZE)
                        return -ENOMEM;
                trace_xfs_buf_backing_fallback(bp, _RET_IP_);
-               goto fallback;
-       }
-       bp->b_addr = folio_address(folio);
-       trace_xfs_buf_backing_folio(bp, _RET_IP_);
-       return 0;
-
-fallback:
-       for (;;) {
-               bp->b_addr = __vmalloc(size, gfp_mask);
-               if (bp->b_addr)
-                       break;
-               if (flags & XBF_READ_AHEAD)
-                       return -ENOMEM;
-               XFS_STATS_INC(bp->b_mount, xb_page_retries);
-               memalloc_retry_wait(gfp_mask);
+               return xfs_buf_alloc_vmalloc(bp, size, gfp_mask, flags);
        }
-
-       trace_xfs_buf_backing_vmalloc(bp, _RET_IP_);
        return 0;
 }