aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-04-02 10:50:19 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-04-02 10:50:19 -0400
commit2c90e5d658424bc71b111eb5a972240d5d06fe86 (patch)
treef46b830654af0f67ef1691353fe4d79943a05465 /fs/btrfs/ctree.c
parentd6025579531b7ea170ba283b171ff7a6bf7d0e12 (diff)
Btrfs: still corruption hunting
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index a0dfa2d6cb9b..453ce835209a 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -16,6 +16,16 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct
16static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 16static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
17 struct btrfs_path *path, int level, int slot); 17 struct btrfs_path *path, int level, int slot);
18 18
19struct btrfs_path *btrfs_alloc_path(void)
20{
21 return kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS);
22}
23
24void btrfs_free_path(struct btrfs_path *p)
25{
26 kmem_cache_free(btrfs_path_cachep, p);
27}
28
19inline void btrfs_init_path(struct btrfs_path *p) 29inline void btrfs_init_path(struct btrfs_path *p)
20{ 30{
21 memset(p, 0, sizeof(*p)); 31 memset(p, 0, sizeof(*p));
@@ -47,17 +57,18 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
47 } 57 }
48 cow = btrfs_alloc_free_block(trans, root); 58 cow = btrfs_alloc_free_block(trans, root);
49 cow_node = btrfs_buffer_node(cow); 59 cow_node = btrfs_buffer_node(cow);
60 if (buf->b_size != root->blocksize || cow->b_size != root->blocksize)
61 WARN_ON(1);
50 memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); 62 memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
51 btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr); 63 btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr);
52 btrfs_set_header_generation(&cow_node->header, trans->transid); 64 btrfs_set_header_generation(&cow_node->header, trans->transid);
53 *cow_ret = cow;
54 btrfs_mark_buffer_dirty(cow);
55 btrfs_inc_ref(trans, root, buf); 65 btrfs_inc_ref(trans, root, buf);
56 if (buf == root->node) { 66 if (buf == root->node) {
57 root->node = cow; 67 root->node = cow;
58 get_bh(cow); 68 get_bh(cow);
59 if (buf != root->commit_root) 69 if (buf != root->commit_root) {
60 btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1); 70 btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1);
71 }
61 btrfs_block_release(root, buf); 72 btrfs_block_release(root, buf);
62 } else { 73 } else {
63 btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot, 74 btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot,
@@ -66,6 +77,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
66 btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1); 77 btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1);
67 } 78 }
68 btrfs_block_release(root, buf); 79 btrfs_block_release(root, buf);
80 *cow_ret = cow;
69 return 0; 81 return 0;
70} 82}
71 83
@@ -477,9 +489,12 @@ again:
477 p->slots[level + 1], 489 p->slots[level + 1],
478 &cow_buf); 490 &cow_buf);
479 b = cow_buf; 491 b = cow_buf;
492 c = btrfs_buffer_node(b);
480 } 493 }
481 BUG_ON(!cow && ins_len); 494 BUG_ON(!cow && ins_len);
482 c = btrfs_buffer_node(b); 495 if (level != btrfs_header_level(&c->header))
496 WARN_ON(1);
497 level = btrfs_header_level(&c->header);
483 p->nodes[level] = b; 498 p->nodes[level] = b;
484 ret = check_block(root, p, level); 499 ret = check_block(root, p, level);
485 if (ret) 500 if (ret)
@@ -1257,19 +1272,22 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
1257 data_size) 1272 data_size)
1258{ 1273{
1259 int ret = 0; 1274 int ret = 0;
1260 struct btrfs_path path; 1275 struct btrfs_path *path;
1261 u8 *ptr; 1276 u8 *ptr;
1262 1277
1263 btrfs_init_path(&path); 1278 path = btrfs_alloc_path();
1264 ret = btrfs_insert_empty_item(trans, root, &path, cpu_key, data_size); 1279 BUG_ON(!path);
1280 btrfs_init_path(path);
1281 ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
1265 if (!ret) { 1282 if (!ret) {
1266 ptr = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), 1283 ptr = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
1267 path.slots[0], u8); 1284 path->slots[0], u8);
1268 btrfs_memcpy(root, path.nodes[0]->b_data, 1285 btrfs_memcpy(root, path->nodes[0]->b_data,
1269 ptr, data, data_size); 1286 ptr, data, data_size);
1270 btrfs_mark_buffer_dirty(path.nodes[0]); 1287 btrfs_mark_buffer_dirty(path->nodes[0]);
1271 } 1288 }
1272 btrfs_release_path(root, &path); 1289 btrfs_release_path(root, path);
1290 btrfs_free_path(path);
1273 return ret; 1291 return ret;
1274} 1292}
1275 1293