btrfs: do an allocation earlier during snapshot creation
[cascardo/linux.git] / fs / btrfs / ioctl.c
index da94138..fa25091 100644 (file)
@@ -655,22 +655,20 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
        if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
                return -EINVAL;
 
+       pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
+       if (!pending_snapshot)
+               return -ENOMEM;
+
        atomic_inc(&root->will_be_snapshoted);
        smp_mb__after_atomic();
        btrfs_wait_for_no_snapshoting_writes(root);
 
        ret = btrfs_start_delalloc_inodes(root, 0);
        if (ret)
-               goto out;
+               goto dec_and_free;
 
        btrfs_wait_ordered_extents(root, -1);
 
-       pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
-       if (!pending_snapshot) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
        btrfs_init_block_rsv(&pending_snapshot->block_rsv,
                             BTRFS_BLOCK_RSV_TEMP);
        /*
@@ -686,7 +684,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
                                        &pending_snapshot->qgroup_reserved,
                                        false);
        if (ret)
-               goto free;
+               goto dec_and_free;
 
        pending_snapshot->dentry = dentry;
        pending_snapshot->root = root;
@@ -737,11 +735,11 @@ fail:
        btrfs_subvolume_release_metadata(BTRFS_I(dir)->root,
                                         &pending_snapshot->block_rsv,
                                         pending_snapshot->qgroup_reserved);
-free:
-       kfree(pending_snapshot);
-out:
+dec_and_free:
        if (atomic_dec_and_test(&root->will_be_snapshoted))
                wake_up_atomic_t(&root->will_be_snapshoted);
+       kfree(pending_snapshot);
+
        return ret;
 }
 
@@ -3478,7 +3476,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
                return ret;
        }
 
-       path->reada = 2;
+       path->reada = READA_FORWARD;
        /* clone data */
        key.objectid = btrfs_ino(src);
        key.type = BTRFS_EXTENT_DATA_KEY;
@@ -5286,7 +5284,7 @@ out_unlock:
 static int btrfs_ioctl_get_supported_features(struct file *file,
                                              void __user *arg)
 {
-       static struct btrfs_ioctl_feature_flags features[3] = {
+       static const struct btrfs_ioctl_feature_flags features[3] = {
                INIT_FEATURE_FLAGS(SUPP),
                INIT_FEATURE_FLAGS(SAFE_SET),
                INIT_FEATURE_FLAGS(SAFE_CLEAR)