@@ -661,7 +661,8 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
pending_snapshot->root_item = kzalloc(sizeof(struct btrfs_root_item),
GFP_NOFS);
- if (!pending_snapshot->root_item) {
+ pending_snapshot->path = btrfs_alloc_path();
+ if (!pending_snapshot->root_item || !pending_snapshot->path) {
ret = -ENOMEM;
goto free_pending;
}
@@ -747,6 +748,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
wake_up_atomic_t(&root->will_be_snapshoted);
free_pending:
kfree(pending_snapshot->root_item);
+ btrfs_free_path(pending_snapshot->path);
kfree(pending_snapshot);
return ret;
@@ -1314,11 +1314,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
u64 root_flags;
uuid_le new_uuid;
- path = btrfs_alloc_path();
- if (!path) {
- pending->error = -ENOMEM;
- return 0;
- }
+ ASSERT(pending->path);
+ path = pending->path;
ASSERT(pending->root_item);
new_root_item = pending->root_item;
@@ -1556,6 +1553,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
kfree(new_root_item);
pending->root_item = NULL;
btrfs_free_path(path);
+ pending->path = NULL;
+
return ret;
}
@@ -141,6 +141,7 @@ struct btrfs_pending_snapshot {
struct btrfs_root_item *root_item;
struct btrfs_root *snap;
struct btrfs_qgroup_inherit *inherit;
+ struct btrfs_path *path;
/* block reservation for the operation */
struct btrfs_block_rsv block_rsv;
u64 qgroup_reserved;
We can also preallocate btrfs_path that's used during pending snapshot creation and avoid another late ENOMEM failure. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/ioctl.c | 4 +++- fs/btrfs/transaction.c | 9 ++++----- fs/btrfs/transaction.h | 1 + 3 files changed, 8 insertions(+), 6 deletions(-)