aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/send.c
diff options
context:
space:
mode:
authorAlexander Block <ablock84@googlemail.com>2012-07-28 06:44:34 -0400
committerChris Mason <chris.mason@fusionio.com>2012-10-01 15:18:49 -0400
commit35075bb046cc91f42a0e5336bdc07f3279061add (patch)
tree7ed070a614d0ad0b80412e93bfefc5902706800b /fs/btrfs/send.c
parentee849c0472a9fe1dc09fe8390965d993b9c4e979 (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.c29
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
1272out: 1278out:
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