diff options
author | Alexander Block <ablock84@googlemail.com> | 2012-07-28 06:44:34 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2012-10-01 15:18:49 -0400 |
commit | 35075bb046cc91f42a0e5336bdc07f3279061add (patch) | |
tree | 7ed070a614d0ad0b80412e93bfefc5902706800b /fs/btrfs/send.c | |
parent | ee849c0472a9fe1dc09fe8390965d993b9c4e979 (diff) |
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>
Diffstat (limited to 'fs/btrfs/send.c')
-rw-r--r-- | fs/btrfs/send.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index a25be0c1a6b9..36711123bdcf 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -1149,7 +1149,7 @@ static int find_extent_clone(struct send_ctx *sctx, | |||
1149 | u64 extent_item_pos; | 1149 | u64 extent_item_pos; |
1150 | struct btrfs_file_extent_item *fi; | 1150 | struct btrfs_file_extent_item *fi; |
1151 | struct extent_buffer *eb = path->nodes[0]; | 1151 | struct extent_buffer *eb = path->nodes[0]; |
1152 | struct backref_ctx backref_ctx; | 1152 | struct backref_ctx *backref_ctx = NULL; |
1153 | struct clone_root *cur_clone_root; | 1153 | struct clone_root *cur_clone_root; |
1154 | struct btrfs_key found_key; | 1154 | struct btrfs_key found_key; |
1155 | struct btrfs_path *tmp_path; | 1155 | struct btrfs_path *tmp_path; |
@@ -1159,6 +1159,12 @@ static int find_extent_clone(struct send_ctx *sctx, | |||
1159 | if (!tmp_path) | 1159 | if (!tmp_path) |
1160 | return -ENOMEM; | 1160 | return -ENOMEM; |
1161 | 1161 | ||
1162 | backref_ctx = kmalloc(sizeof(*backref_ctx), GFP_NOFS); | ||
1163 | if (!backref_ctx) { | ||
1164 | ret = -ENOMEM; | ||
1165 | goto out; | ||
1166 | } | ||
1167 | |||
1162 | if (data_offset >= ino_size) { | 1168 | if (data_offset >= ino_size) { |
1163 | /* | 1169 | /* |
1164 | * There may be extents that lie behind the file's size. | 1170 | * There may be extents that lie behind the file's size. |
@@ -1206,12 +1212,12 @@ static int find_extent_clone(struct send_ctx *sctx, | |||
1206 | cur_clone_root->found_refs = 0; | 1212 | cur_clone_root->found_refs = 0; |
1207 | } | 1213 | } |
1208 | 1214 | ||
1209 | backref_ctx.sctx = sctx; | 1215 | backref_ctx->sctx = sctx; |
1210 | backref_ctx.found = 0; | 1216 | backref_ctx->found = 0; |
1211 | backref_ctx.cur_objectid = ino; | 1217 | backref_ctx->cur_objectid = ino; |
1212 | backref_ctx.cur_offset = data_offset; | 1218 | backref_ctx->cur_offset = data_offset; |
1213 | backref_ctx.found_itself = 0; | 1219 | backref_ctx->found_itself = 0; |
1214 | backref_ctx.extent_len = num_bytes; | 1220 | backref_ctx->extent_len = num_bytes; |
1215 | 1221 | ||
1216 | /* | 1222 | /* |
1217 | * The last extent of a file may be too large due to page alignment. | 1223 | * 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, | |||
1219 | * __iterate_backrefs work. | 1225 | * __iterate_backrefs work. |
1220 | */ | 1226 | */ |
1221 | if (data_offset + num_bytes >= ino_size) | 1227 | if (data_offset + num_bytes >= ino_size) |
1222 | backref_ctx.extent_len = ino_size - data_offset; | 1228 | backref_ctx->extent_len = ino_size - data_offset; |
1223 | 1229 | ||
1224 | /* | 1230 | /* |
1225 | * Now collect all backrefs. | 1231 | * Now collect all backrefs. |
@@ -1227,11 +1233,11 @@ static int find_extent_clone(struct send_ctx *sctx, | |||
1227 | extent_item_pos = logical - found_key.objectid; | 1233 | extent_item_pos = logical - found_key.objectid; |
1228 | ret = iterate_extent_inodes(sctx->send_root->fs_info, | 1234 | ret = iterate_extent_inodes(sctx->send_root->fs_info, |
1229 | found_key.objectid, extent_item_pos, 1, | 1235 | found_key.objectid, extent_item_pos, 1, |
1230 | __iterate_backrefs, &backref_ctx); | 1236 | __iterate_backrefs, backref_ctx); |
1231 | if (ret < 0) | 1237 | if (ret < 0) |
1232 | goto out; | 1238 | goto out; |
1233 | 1239 | ||
1234 | if (!backref_ctx.found_itself) { | 1240 | if (!backref_ctx->found_itself) { |
1235 | /* found a bug in backref code? */ | 1241 | /* found a bug in backref code? */ |
1236 | ret = -EIO; | 1242 | ret = -EIO; |
1237 | printk(KERN_ERR "btrfs: ERROR did not find backref in " | 1243 | 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, " | |||
1246 | "num_bytes=%llu, logical=%llu\n", | 1252 | "num_bytes=%llu, logical=%llu\n", |
1247 | data_offset, ino, num_bytes, logical); | 1253 | data_offset, ino, num_bytes, logical); |
1248 | 1254 | ||
1249 | if (!backref_ctx.found) | 1255 | if (!backref_ctx->found) |
1250 | verbose_printk("btrfs: no clones found\n"); | 1256 | verbose_printk("btrfs: no clones found\n"); |
1251 | 1257 | ||
1252 | cur_clone_root = NULL; | 1258 | cur_clone_root = NULL; |
@@ -1271,6 +1277,7 @@ verbose_printk(KERN_DEBUG "btrfs: find_extent_clone: data_offset=%llu, " | |||
1271 | 1277 | ||
1272 | out: | 1278 | out: |
1273 | btrfs_free_path(tmp_path); | 1279 | btrfs_free_path(tmp_path); |
1280 | kfree(backref_ctx); | ||
1274 | return ret; | 1281 | return ret; |
1275 | } | 1282 | } |
1276 | 1283 | ||