Commit a1ee7362 authored by David Sterba's avatar David Sterba

btrfs: do an allocation earlier during snapshot creation

We can allocate pending_snapshot earlier and do not have to do cleanup
in case of failure.
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 4fb72bf2
...@@ -655,22 +655,20 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, ...@@ -655,22 +655,20 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state)) if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
return -EINVAL; return -EINVAL;
pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
if (!pending_snapshot)
return -ENOMEM;
atomic_inc(&root->will_be_snapshoted); atomic_inc(&root->will_be_snapshoted);
smp_mb__after_atomic(); smp_mb__after_atomic();
btrfs_wait_for_no_snapshoting_writes(root); btrfs_wait_for_no_snapshoting_writes(root);
ret = btrfs_start_delalloc_inodes(root, 0); ret = btrfs_start_delalloc_inodes(root, 0);
if (ret) if (ret)
goto out; goto dec_and_free;
btrfs_wait_ordered_extents(root, -1); 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_init_block_rsv(&pending_snapshot->block_rsv,
BTRFS_BLOCK_RSV_TEMP); BTRFS_BLOCK_RSV_TEMP);
/* /*
...@@ -686,7 +684,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, ...@@ -686,7 +684,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
&pending_snapshot->qgroup_reserved, &pending_snapshot->qgroup_reserved,
false); false);
if (ret) if (ret)
goto free; goto dec_and_free;
pending_snapshot->dentry = dentry; pending_snapshot->dentry = dentry;
pending_snapshot->root = root; pending_snapshot->root = root;
...@@ -737,11 +735,11 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, ...@@ -737,11 +735,11 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
btrfs_subvolume_release_metadata(BTRFS_I(dir)->root, btrfs_subvolume_release_metadata(BTRFS_I(dir)->root,
&pending_snapshot->block_rsv, &pending_snapshot->block_rsv,
pending_snapshot->qgroup_reserved); pending_snapshot->qgroup_reserved);
free: dec_and_free:
kfree(pending_snapshot);
out:
if (atomic_dec_and_test(&root->will_be_snapshoted)) if (atomic_dec_and_test(&root->will_be_snapshoted))
wake_up_atomic_t(&root->will_be_snapshoted); wake_up_atomic_t(&root->will_be_snapshoted);
kfree(pending_snapshot);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment