Btrfs: use kmalloc instead of stack for backref_ctx

Make sure to never get in trouble due to the backref_ctx
which was on the stack before.

Commit is a result of Arne's review.

Signed-off-by: Alexander Block <ablock84@googlemail.com>
This commit is contained in:
Alexander Block 2012-07-28 12:44:34 +02:00 committed by Chris Mason
parent ee849c0472
commit 35075bb046
1 changed files with 18 additions and 11 deletions

View File

@ -1149,7 +1149,7 @@ static int find_extent_clone(struct send_ctx *sctx,
u64 extent_item_pos; u64 extent_item_pos;
struct btrfs_file_extent_item *fi; struct btrfs_file_extent_item *fi;
struct extent_buffer *eb = path->nodes[0]; struct extent_buffer *eb = path->nodes[0];
struct backref_ctx backref_ctx; struct backref_ctx *backref_ctx = NULL;
struct clone_root *cur_clone_root; struct clone_root *cur_clone_root;
struct btrfs_key found_key; struct btrfs_key found_key;
struct btrfs_path *tmp_path; struct btrfs_path *tmp_path;
@ -1159,6 +1159,12 @@ static int find_extent_clone(struct send_ctx *sctx,
if (!tmp_path) if (!tmp_path)
return -ENOMEM; return -ENOMEM;
backref_ctx = kmalloc(sizeof(*backref_ctx), GFP_NOFS);
if (!backref_ctx) {
ret = -ENOMEM;
goto out;
}
if (data_offset >= ino_size) { if (data_offset >= ino_size) {
/* /*
* There may be extents that lie behind the file's size. * There may be extents that lie behind the file's size.
@ -1206,12 +1212,12 @@ static int find_extent_clone(struct send_ctx *sctx,
cur_clone_root->found_refs = 0; cur_clone_root->found_refs = 0;
} }
backref_ctx.sctx = sctx; backref_ctx->sctx = sctx;
backref_ctx.found = 0; backref_ctx->found = 0;
backref_ctx.cur_objectid = ino; backref_ctx->cur_objectid = ino;
backref_ctx.cur_offset = data_offset; backref_ctx->cur_offset = data_offset;
backref_ctx.found_itself = 0; backref_ctx->found_itself = 0;
backref_ctx.extent_len = num_bytes; backref_ctx->extent_len = num_bytes;
/* /*
* The last extent of a file may be too large due to page alignment. * The last extent of a file may be too large due to page alignment.
@ -1219,7 +1225,7 @@ static int find_extent_clone(struct send_ctx *sctx,
* __iterate_backrefs work. * __iterate_backrefs work.
*/ */
if (data_offset + num_bytes >= ino_size) if (data_offset + num_bytes >= ino_size)
backref_ctx.extent_len = ino_size - data_offset; backref_ctx->extent_len = ino_size - data_offset;
/* /*
* Now collect all backrefs. * Now collect all backrefs.
@ -1227,11 +1233,11 @@ static int find_extent_clone(struct send_ctx *sctx,
extent_item_pos = logical - found_key.objectid; extent_item_pos = logical - found_key.objectid;
ret = iterate_extent_inodes(sctx->send_root->fs_info, ret = iterate_extent_inodes(sctx->send_root->fs_info,
found_key.objectid, extent_item_pos, 1, found_key.objectid, extent_item_pos, 1,
__iterate_backrefs, &backref_ctx); __iterate_backrefs, backref_ctx);
if (ret < 0) if (ret < 0)
goto out; goto out;
if (!backref_ctx.found_itself) { if (!backref_ctx->found_itself) {
/* found a bug in backref code? */ /* found a bug in backref code? */
ret = -EIO; ret = -EIO;
printk(KERN_ERR "btrfs: ERROR did not find backref in " printk(KERN_ERR "btrfs: ERROR did not find backref in "
@ -1246,7 +1252,7 @@ verbose_printk(KERN_DEBUG "btrfs: find_extent_clone: data_offset=%llu, "
"num_bytes=%llu, logical=%llu\n", "num_bytes=%llu, logical=%llu\n",
data_offset, ino, num_bytes, logical); data_offset, ino, num_bytes, logical);
if (!backref_ctx.found) if (!backref_ctx->found)
verbose_printk("btrfs: no clones found\n"); verbose_printk("btrfs: no clones found\n");
cur_clone_root = NULL; cur_clone_root = NULL;
@ -1271,6 +1277,7 @@ verbose_printk(KERN_DEBUG "btrfs: find_extent_clone: data_offset=%llu, "
out: out:
btrfs_free_path(tmp_path); btrfs_free_path(tmp_path);
kfree(backref_ctx);
return ret; return ret;
} }