]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: make xfs_bmapi_convert_delalloc() to allocate the target offset
authorZhang Yi <yi.zhang@huawei.com>
Thu, 25 Apr 2024 13:13:29 +0000 (21:13 +0800)
committerChandan Babu R <chandanbabu@kernel.org>
Mon, 29 Apr 2024 11:53:11 +0000 (17:23 +0530)
Since xfs_bmapi_convert_delalloc() only attempts to allocate the entire
delalloc extent and require multiple invocations to allocate the target
offset. So xfs_convert_blocks() add a loop to do this job and we call it
in the write back path, but xfs_convert_blocks() isn't a common helper.
Let's do it in xfs_bmapi_convert_delalloc() and drop
xfs_convert_blocks(), preparing for the post EOF delalloc blocks
converting in the buffered write begin path.

Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/xfs_aops.c

index c9b1dfe639444ae7f5aafe432dc0b366ecaec2f6..49e2fcad593df39f5b1fffd96801f51d39d3d37b 100644 (file)
@@ -4590,8 +4590,8 @@ error0:
  * invocations to allocate the target offset if a large enough physical extent
  * is not available.
  */
-int
-xfs_bmapi_convert_delalloc(
+static int
+xfs_bmapi_convert_one_delalloc(
        struct xfs_inode        *ip,
        int                     whichfork,
        xfs_off_t               offset,
@@ -4724,6 +4724,36 @@ out_trans_cancel:
        return error;
 }
 
+/*
+ * Pass in a dellalloc extent and convert it to real extents, return the real
+ * extent that maps offset_fsb in iomap.
+ */
+int
+xfs_bmapi_convert_delalloc(
+       struct xfs_inode        *ip,
+       int                     whichfork,
+       loff_t                  offset,
+       struct iomap            *iomap,
+       unsigned int            *seq)
+{
+       int                     error;
+
+       /*
+        * Attempt to allocate whatever delalloc extent currently backs offset
+        * and put the result into iomap.  Allocate in a loop because it may
+        * take several attempts to allocate real blocks for a contiguous
+        * delalloc extent if free space is sufficiently fragmented.
+        */
+       do {
+               error = xfs_bmapi_convert_one_delalloc(ip, whichfork, offset,
+                                       iomap, seq);
+               if (error)
+                       return error;
+       } while (iomap->offset + iomap->length <= offset);
+
+       return 0;
+}
+
 int
 xfs_bmapi_remap(
        struct xfs_trans        *tp,
index 3f428620ebf2a395d8efdcb3094f8c940cdc3310..f7520f375ceeee77660d9c6224cad3f0a5f717d4 100644 (file)
@@ -233,45 +233,6 @@ xfs_imap_valid(
        return true;
 }
 
-/*
- * Pass in a dellalloc extent and convert it to real extents, return the real
- * extent that maps offset_fsb in wpc->iomap.
- *
- * The current page is held locked so nothing could have removed the block
- * backing offset_fsb, although it could have moved from the COW to the data
- * fork by another thread.
- */
-static int
-xfs_convert_blocks(
-       struct iomap_writepage_ctx *wpc,
-       struct xfs_inode        *ip,
-       int                     whichfork,
-       loff_t                  offset)
-{
-       int                     error;
-       unsigned                *seq;
-
-       if (whichfork == XFS_COW_FORK)
-               seq = &XFS_WPC(wpc)->cow_seq;
-       else
-               seq = &XFS_WPC(wpc)->data_seq;
-
-       /*
-        * Attempt to allocate whatever delalloc extent currently backs offset
-        * and put the result into wpc->iomap.  Allocate in a loop because it
-        * may take several attempts to allocate real blocks for a contiguous
-        * delalloc extent if free space is sufficiently fragmented.
-        */
-       do {
-               error = xfs_bmapi_convert_delalloc(ip, whichfork, offset,
-                               &wpc->iomap, seq);
-               if (error)
-                       return error;
-       } while (wpc->iomap.offset + wpc->iomap.length <= offset);
-
-       return 0;
-}
-
 static int
 xfs_map_blocks(
        struct iomap_writepage_ctx *wpc,
@@ -290,6 +251,7 @@ xfs_map_blocks(
        struct xfs_iext_cursor  icur;
        int                     retries = 0;
        int                     error = 0;
+       unsigned int            *seq;
 
        if (xfs_is_shutdown(mp))
                return -EIO;
@@ -387,7 +349,19 @@ retry:
        trace_xfs_map_blocks_found(ip, offset, count, whichfork, &imap);
        return 0;
 allocate_blocks:
-       error = xfs_convert_blocks(wpc, ip, whichfork, offset);
+       /*
+        * Convert a dellalloc extent to a real one. The current page is held
+        * locked so nothing could have removed the block backing offset_fsb,
+        * although it could have moved from the COW to the data fork by another
+        * thread.
+        */
+       if (whichfork == XFS_COW_FORK)
+               seq = &XFS_WPC(wpc)->cow_seq;
+       else
+               seq = &XFS_WPC(wpc)->data_seq;
+
+       error = xfs_bmapi_convert_delalloc(ip, whichfork, offset,
+                               &wpc->iomap, seq);
        if (error) {
                /*
                 * If we failed to find the extent in the COW fork we might have