|
@@ -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;
|
|
|
}
|
|
|
|