mirror of https://gitee.com/openkylin/linux.git
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:
parent
ee849c0472
commit
35075bb046
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue