diff options
author | David Sterba <dsterba@suse.com> | 2015-11-10 18:54:00 +0100 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2016-01-07 15:20:54 +0100 |
commit | b0c0ea6338d5018e02d27c5315084fb1a5d099f6 (patch) | |
tree | bf2aa288dd2d98143b12ea1753739491c7eda54d /fs/btrfs/transaction.c | |
parent | a1ee736268448d74af25737568e383acb84c3c18 (diff) |
btrfs: allocate root item at snapshot ioctl time
The actual snapshot creation is delayed until transaction commit. If we
cannot get enough memory for the root item there, we have to fail the
whole transaction commit which is bad. So we'll allocate the memory at
the ioctl call and pass it along with the pending_snapshot struct. The
potential ENOMEM will be returned to the caller of snapshot ioctl.
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index be8eae80ff65..2074106122d9 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1325,11 +1325,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, return 0; } - new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); - if (!new_root_item) { - pending->error = -ENOMEM; - goto root_item_alloc_fail; - } + ASSERT(pending->root_item); + new_root_item = pending->root_item; pending->error = btrfs_find_free_objectid(tree_root, &objectid); if (pending->error) @@ -1562,7 +1559,7 @@ clear_skip_qgroup: btrfs_clear_skip_qgroup(trans); no_free_objectid: kfree(new_root_item); -root_item_alloc_fail: + pending->root_item = NULL; btrfs_free_path(path); return ret; } |