From: Dave Chinner <dchin...@redhat.com>

Provision space in the block device for preallocated file space when
userspace asks for it. Make sure to do this outside of transaction
context so it can fail without causing a filesystem shutdown.

XXX: async provisioning submission/completion interface would be
really useful here....

Signed-off-by: Dave Chinner <dchin...@redhat.com>
---
 fs/xfs/xfs_bmap_util.c | 42 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index fcefab687285..5dddd1e7bc47 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -772,6 +772,37 @@ xfs_free_eofblocks(
        return error;
 }
 
+static int
+xfs_bmap_provision_blocks(
+       struct xfs_inode        *ip,
+       struct xfs_bmbt_irec    *imap,
+       int                     nimaps)
+{
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_buftarg      *target;
+       int                     i;
+
+       if (!xfs_is_provisioning_blocks(mp))
+               return 0;
+
+       target = xfs_inode_buftarg(ip);
+       if (!target->bt_needs_provisioning)
+               return 0;
+
+       for (i = 0; i < nimaps; i++) {
+               int     error;
+
+               error = blkdev_issue_provision(target->bt_bdev,
+                               XFS_FSB_TO_DADDR(mp, imap->br_startblock),
+                               XFS_FSB_TO_BB(mp, imap->br_blockcount),
+                               GFP_KERNEL, 0);
+               ASSERT(error != -EOPNOTSUPP);
+               if (error)
+                       return error;
+       }
+       return 0;
+}
+
 int
 xfs_alloc_file_space(
        struct xfs_inode        *ip,
@@ -780,7 +811,6 @@ xfs_alloc_file_space(
 {
        xfs_mount_t             *mp = ip->i_mount;
        xfs_off_t               count;
-       xfs_filblks_t           allocated_fsb;
        xfs_filblks_t           allocatesize_fsb;
        xfs_extlen_t            extsz, temp;
        xfs_fileoff_t           startoffset_fsb;
@@ -884,15 +914,17 @@ xfs_alloc_file_space(
                if (error)
                        break;
 
-               allocated_fsb = imapp->br_blockcount;
-
                if (nimaps == 0) {
                        error = -ENOSPC;
                        break;
                }
 
-               startoffset_fsb += allocated_fsb;
-               allocatesize_fsb -= allocated_fsb;
+               error = xfs_bmap_provision_blocks(ip, imapp, nimaps);
+               if (error)
+                       break;
+
+               startoffset_fsb += imapp->br_blockcount;
+               allocatesize_fsb -= imapp->br_blockcount;
        }
 
        return error;

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel

Reply via email to