Pull out the actual free space check, so setting an inode's initial
space_info is done by the caller instead of a wonky goto.

Signed-off-by: Sage Weil <s...@newdream.net>
---
 fs/btrfs/extent-tree.c |   81 +++++++++++++++++++++++++++++------------------
 1 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 63d86ae..cb50944 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2830,25 +2830,33 @@ alloc:
        return 0;
 }
 
-/*
- * This will check the space that the inode allocates from to make sure we have
- * enough space for bytes.
- */
-int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
-                               u64 bytes)
+static int __alloc_chunk(struct btrfs_root *root, u64 bytes)
 {
-       struct btrfs_space_info *data_sinfo;
-       int ret = 0, committed = 0;
+       int ret;
+       u64 alloc_target;
+       struct btrfs_trans_handle *trans;
 
-       /* make sure bytes are sectorsize aligned */
-       bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
+       alloc_target = btrfs_get_alloc_profile(root, 1);
+       trans = btrfs_start_transaction(root, 1);
+       if (!trans)
+               return -ENOMEM;
 
-       data_sinfo = BTRFS_I(inode)->space_info;
-       if (!data_sinfo)
-               goto alloc;
+       ret = do_chunk_alloc(trans, root->fs_info->extent_root,
+                            bytes + 2 * 1024 * 1024,
+                            alloc_target, 0);
+       btrfs_end_transaction(trans, root);
+       return ret;
+}
+
+int btrfs_check_data_free_space_info(struct btrfs_root *root,
+                                    struct btrfs_space_info *data_sinfo,
+                                    u64 bytes,
+                                    struct inode *inode)
+{
+       int ret = 0, committed = 0;
 
-again:
        /* make sure we have enough space to handle the data first */
+again:
        spin_lock(&data_sinfo->lock);
        if (data_sinfo->total_bytes - data_sinfo->bytes_used -
            data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved -
@@ -2861,27 +2869,11 @@ again:
                 * to alloc a new chunk.
                 */
                if (!data_sinfo->full) {
-                       u64 alloc_target;
-
                        data_sinfo->force_alloc = 1;
                        spin_unlock(&data_sinfo->lock);
-alloc:
-                       alloc_target = btrfs_get_alloc_profile(root, 1);
-                       trans = btrfs_start_transaction(root, 1);
-                       if (!trans)
-                               return -ENOMEM;
-
-                       ret = do_chunk_alloc(trans, root->fs_info->extent_root,
-                                            bytes + 2 * 1024 * 1024,
-                                            alloc_target, 0);
-                       btrfs_end_transaction(trans, root);
+                       ret = __alloc_chunk(root, bytes);
                        if (ret)
                                return ret;
-
-                       if (!data_sinfo) {
-                               btrfs_set_inode_space_info(root, inode);
-                               data_sinfo = BTRFS_I(inode)->space_info;
-                       }
                        goto again;
                }
                spin_unlock(&data_sinfo->lock);
@@ -2914,7 +2906,34 @@ alloc:
        data_sinfo->bytes_may_use += bytes;
        BTRFS_I(inode)->reserved_bytes += bytes;
        spin_unlock(&data_sinfo->lock);
+       return 0;
+}
 
+/*
+ * This will check the space that the inode allocates from to make sure we have
+ * enough space for bytes.
+ */
+int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
+                               u64 bytes)
+{
+       struct btrfs_space_info *data_sinfo;
+       int ret;
+
+       /* make sure bytes are sectorsize aligned */
+       bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
+
+       data_sinfo = BTRFS_I(inode)->space_info;
+       if (!data_sinfo) {
+               ret = __alloc_chunk(root, bytes);
+               if (ret)
+                       return ret;
+               btrfs_set_inode_space_info(root, inode);
+               data_sinfo = BTRFS_I(inode)->space_info;
+       }
+
+       ret = btrfs_check_data_free_space_info(root, data_sinfo, bytes, inode);
+       if (ret)
+               return ret;
        return btrfs_check_metadata_free_space(root);
 }
 
-- 
1.5.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to