]> git.apps.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs: make xfs_bmapi_convert_delalloc() to allocate the target offset
authorZhang Yi <yi.zhang@huawei.com>
Mon, 29 Jul 2024 23:22:54 +0000 (16:22 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:01:04 +0000 (17:01 -0700)
Source kernel commit: 2e08371a83f1c06fd85eea8cd37c87a224cc4cc4

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

index 0234440829ed69a5b9aa7511d5185a9d3501db11..90b2db091d70b7ddb2c3ddc5825509e584145c6d 100644 (file)
@@ -79,7 +79,10 @@ extern struct kmem_cache *xfs_trans_cache;
 #define crc32c(c,p,l)  crc32c_le((c),(unsigned char const *)(p),(l))
 
 /* fake up kernel's iomap, (not) used in xfs_bmap.[ch] */
-struct iomap;
+struct iomap {
+       unsigned long long      offset; /* do not use */
+       unsigned long long      length; /* do not use */
+};
 
 #define cancel_delayed_work_sync(work) do { } while(0)
 
index 33d0764a0a8418957b97d50fb51237ff1ba0cf6a..9fce05e1f168777facd721481b072216ee03ed1f 100644 (file)
@@ -4584,8 +4584,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,
@@ -4718,6 +4718,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,