diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-12-11 09:25:06 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:58 -0400 |
commit | 7bb86316c3961d1bc401ef184fd996f999556c7f (patch) | |
tree | e67de3b594cf680f295010095a71ed7e825cb757 /fs/btrfs/ctree.c | |
parent | 74493f7a59bfd4d1c7029c74ab2cd0e400612c6b (diff) |
Btrfs: Add back pointers from extents to the btree or file referencing them
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 196 |
1 files changed, 176 insertions, 20 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 5697705f7530..fd8233e05cf4 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -77,13 +77,37 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
77 | struct extent_buffer **cow_ret, | 77 | struct extent_buffer **cow_ret, |
78 | u64 search_start, u64 empty_size) | 78 | u64 search_start, u64 empty_size) |
79 | { | 79 | { |
80 | u64 root_gen; | ||
80 | struct extent_buffer *cow; | 81 | struct extent_buffer *cow; |
82 | u32 nritems; | ||
81 | int ret = 0; | 83 | int ret = 0; |
82 | int different_trans = 0; | 84 | int different_trans = 0; |
85 | int level; | ||
86 | struct btrfs_key first_key; | ||
87 | |||
88 | if (root->ref_cows) { | ||
89 | root_gen = trans->transid; | ||
90 | } else { | ||
91 | root_gen = 0; | ||
92 | } | ||
83 | 93 | ||
94 | WARN_ON(root->ref_cows && trans->transid != | ||
95 | root->fs_info->running_transaction->transid); | ||
84 | WARN_ON(root->ref_cows && trans->transid != root->last_trans); | 96 | WARN_ON(root->ref_cows && trans->transid != root->last_trans); |
85 | 97 | ||
86 | cow = btrfs_alloc_free_block(trans, root, buf->len, | 98 | level = btrfs_header_level(buf); |
99 | nritems = btrfs_header_nritems(buf); | ||
100 | if (nritems) { | ||
101 | if (level == 0) | ||
102 | btrfs_item_key_to_cpu(buf, &first_key, 0); | ||
103 | else | ||
104 | btrfs_node_key_to_cpu(buf, &first_key, 0); | ||
105 | } else { | ||
106 | first_key.objectid = 0; | ||
107 | } | ||
108 | cow = __btrfs_alloc_free_block(trans, root, buf->len, | ||
109 | root->root_key.objectid, | ||
110 | root_gen, first_key.objectid, level, | ||
87 | search_start, empty_size); | 111 | search_start, empty_size); |
88 | if (IS_ERR(cow)) | 112 | if (IS_ERR(cow)) |
89 | return PTR_ERR(cow); | 113 | return PTR_ERR(cow); |
@@ -104,14 +128,17 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
104 | } | 128 | } |
105 | 129 | ||
106 | if (buf == root->node) { | 130 | if (buf == root->node) { |
131 | root_gen = btrfs_header_generation(buf); | ||
107 | root->node = cow; | 132 | root->node = cow; |
108 | extent_buffer_get(cow); | 133 | extent_buffer_get(cow); |
109 | if (buf != root->commit_root) { | 134 | if (buf != root->commit_root) { |
110 | btrfs_free_extent(trans, root, buf->start, | 135 | btrfs_free_extent(trans, root, buf->start, |
111 | buf->len, 1); | 136 | buf->len, root->root_key.objectid, |
137 | root_gen, 0, 0, 1); | ||
112 | } | 138 | } |
113 | free_extent_buffer(buf); | 139 | free_extent_buffer(buf); |
114 | } else { | 140 | } else { |
141 | root_gen = btrfs_header_generation(parent); | ||
115 | btrfs_set_node_blockptr(parent, parent_slot, | 142 | btrfs_set_node_blockptr(parent, parent_slot, |
116 | cow->start); | 143 | cow->start); |
117 | WARN_ON(trans->transid == 0); | 144 | WARN_ON(trans->transid == 0); |
@@ -119,7 +146,9 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
119 | trans->transid); | 146 | trans->transid); |
120 | btrfs_mark_buffer_dirty(parent); | 147 | btrfs_mark_buffer_dirty(parent); |
121 | WARN_ON(btrfs_header_generation(parent) != trans->transid); | 148 | WARN_ON(btrfs_header_generation(parent) != trans->transid); |
122 | btrfs_free_extent(trans, root, buf->start, buf->len, 1); | 149 | btrfs_free_extent(trans, root, buf->start, buf->len, |
150 | btrfs_header_owner(parent), root_gen, | ||
151 | 0, 0, 1); | ||
123 | } | 152 | } |
124 | free_extent_buffer(buf); | 153 | free_extent_buffer(buf); |
125 | btrfs_mark_buffer_dirty(cow); | 154 | btrfs_mark_buffer_dirty(cow); |
@@ -606,6 +635,8 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
606 | return 0; | 635 | return 0; |
607 | 636 | ||
608 | mid = path->nodes[level]; | 637 | mid = path->nodes[level]; |
638 | WARN_ON(btrfs_header_generation(mid) != trans->transid); | ||
639 | |||
609 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); | 640 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); |
610 | 641 | ||
611 | if (level < BTRFS_MAX_LEVEL - 1) | 642 | if (level < BTRFS_MAX_LEVEL - 1) |
@@ -631,7 +662,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
631 | wait_on_tree_block_writeback(root, mid); | 662 | wait_on_tree_block_writeback(root, mid); |
632 | /* once for the path */ | 663 | /* once for the path */ |
633 | free_extent_buffer(mid); | 664 | free_extent_buffer(mid); |
634 | ret = btrfs_free_extent(trans, root, mid->start, mid->len, 1); | 665 | ret = btrfs_free_extent(trans, root, mid->start, mid->len, |
666 | root->root_key.objectid, | ||
667 | btrfs_header_generation(mid), 0, 0, 1); | ||
635 | /* once for the root ptr */ | 668 | /* once for the root ptr */ |
636 | free_extent_buffer(mid); | 669 | free_extent_buffer(mid); |
637 | return ret; | 670 | return ret; |
@@ -681,6 +714,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
681 | ret = wret; | 714 | ret = wret; |
682 | if (btrfs_header_nritems(right) == 0) { | 715 | if (btrfs_header_nritems(right) == 0) { |
683 | u64 bytenr = right->start; | 716 | u64 bytenr = right->start; |
717 | u64 generation = btrfs_header_generation(parent); | ||
684 | u32 blocksize = right->len; | 718 | u32 blocksize = right->len; |
685 | 719 | ||
686 | clean_tree_block(trans, root, right); | 720 | clean_tree_block(trans, root, right); |
@@ -692,7 +726,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
692 | if (wret) | 726 | if (wret) |
693 | ret = wret; | 727 | ret = wret; |
694 | wret = btrfs_free_extent(trans, root, bytenr, | 728 | wret = btrfs_free_extent(trans, root, bytenr, |
695 | blocksize, 1); | 729 | blocksize, |
730 | btrfs_header_owner(parent), | ||
731 | generation, 0, 0, 1); | ||
696 | if (wret) | 732 | if (wret) |
697 | ret = wret; | 733 | ret = wret; |
698 | } else { | 734 | } else { |
@@ -722,6 +758,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
722 | } | 758 | } |
723 | if (btrfs_header_nritems(mid) == 0) { | 759 | if (btrfs_header_nritems(mid) == 0) { |
724 | /* we've managed to empty the middle node, drop it */ | 760 | /* we've managed to empty the middle node, drop it */ |
761 | u64 root_gen = btrfs_header_generation(parent); | ||
725 | u64 bytenr = mid->start; | 762 | u64 bytenr = mid->start; |
726 | u32 blocksize = mid->len; | 763 | u32 blocksize = mid->len; |
727 | clean_tree_block(trans, root, mid); | 764 | clean_tree_block(trans, root, mid); |
@@ -731,7 +768,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root | |||
731 | wret = del_ptr(trans, root, path, level + 1, pslot); | 768 | wret = del_ptr(trans, root, path, level + 1, pslot); |
732 | if (wret) | 769 | if (wret) |
733 | ret = wret; | 770 | ret = wret; |
734 | wret = btrfs_free_extent(trans, root, bytenr, blocksize, 1); | 771 | wret = btrfs_free_extent(trans, root, bytenr, blocksize, |
772 | btrfs_header_owner(parent), | ||
773 | root_gen, 0, 0, 1); | ||
735 | if (wret) | 774 | if (wret) |
736 | ret = wret; | 775 | ret = wret; |
737 | } else { | 776 | } else { |
@@ -788,6 +827,7 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
788 | return 1; | 827 | return 1; |
789 | 828 | ||
790 | mid = path->nodes[level]; | 829 | mid = path->nodes[level]; |
830 | WARN_ON(btrfs_header_generation(mid) != trans->transid); | ||
791 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); | 831 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); |
792 | 832 | ||
793 | if (level < BTRFS_MAX_LEVEL - 1) | 833 | if (level < BTRFS_MAX_LEVEL - 1) |
@@ -1113,6 +1153,8 @@ static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1113 | src_nritems = btrfs_header_nritems(src); | 1153 | src_nritems = btrfs_header_nritems(src); |
1114 | dst_nritems = btrfs_header_nritems(dst); | 1154 | dst_nritems = btrfs_header_nritems(dst); |
1115 | push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; | 1155 | push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; |
1156 | WARN_ON(btrfs_header_generation(src) != trans->transid); | ||
1157 | WARN_ON(btrfs_header_generation(dst) != trans->transid); | ||
1116 | 1158 | ||
1117 | if (push_items <= 0) { | 1159 | if (push_items <= 0) { |
1118 | return 1; | 1160 | return 1; |
@@ -1159,6 +1201,9 @@ static int balance_node_right(struct btrfs_trans_handle *trans, | |||
1159 | int dst_nritems; | 1201 | int dst_nritems; |
1160 | int ret = 0; | 1202 | int ret = 0; |
1161 | 1203 | ||
1204 | WARN_ON(btrfs_header_generation(src) != trans->transid); | ||
1205 | WARN_ON(btrfs_header_generation(dst) != trans->transid); | ||
1206 | |||
1162 | src_nritems = btrfs_header_nritems(src); | 1207 | src_nritems = btrfs_header_nritems(src); |
1163 | dst_nritems = btrfs_header_nritems(dst); | 1208 | dst_nritems = btrfs_header_nritems(dst); |
1164 | push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; | 1209 | push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems; |
@@ -1202,6 +1247,8 @@ static int insert_new_root(struct btrfs_trans_handle *trans, | |||
1202 | struct btrfs_root *root, | 1247 | struct btrfs_root *root, |
1203 | struct btrfs_path *path, int level) | 1248 | struct btrfs_path *path, int level) |
1204 | { | 1249 | { |
1250 | u64 root_gen; | ||
1251 | u64 lower_gen; | ||
1205 | struct extent_buffer *lower; | 1252 | struct extent_buffer *lower; |
1206 | struct extent_buffer *c; | 1253 | struct extent_buffer *c; |
1207 | struct btrfs_disk_key lower_key; | 1254 | struct btrfs_disk_key lower_key; |
@@ -1209,7 +1256,20 @@ static int insert_new_root(struct btrfs_trans_handle *trans, | |||
1209 | BUG_ON(path->nodes[level]); | 1256 | BUG_ON(path->nodes[level]); |
1210 | BUG_ON(path->nodes[level-1] != root->node); | 1257 | BUG_ON(path->nodes[level-1] != root->node); |
1211 | 1258 | ||
1212 | c = btrfs_alloc_free_block(trans, root, root->nodesize, | 1259 | if (root->ref_cows) |
1260 | root_gen = trans->transid; | ||
1261 | else | ||
1262 | root_gen = 0; | ||
1263 | |||
1264 | lower = path->nodes[level-1]; | ||
1265 | if (level == 1) | ||
1266 | btrfs_item_key(lower, &lower_key, 0); | ||
1267 | else | ||
1268 | btrfs_node_key(lower, &lower_key, 0); | ||
1269 | |||
1270 | c = __btrfs_alloc_free_block(trans, root, root->nodesize, | ||
1271 | root->root_key.objectid, | ||
1272 | root_gen, lower_key.objectid, level, | ||
1213 | root->node->start, 0); | 1273 | root->node->start, 0); |
1214 | if (IS_ERR(c)) | 1274 | if (IS_ERR(c)) |
1215 | return PTR_ERR(c); | 1275 | return PTR_ERR(c); |
@@ -1219,19 +1279,16 @@ static int insert_new_root(struct btrfs_trans_handle *trans, | |||
1219 | btrfs_set_header_bytenr(c, c->start); | 1279 | btrfs_set_header_bytenr(c, c->start); |
1220 | btrfs_set_header_generation(c, trans->transid); | 1280 | btrfs_set_header_generation(c, trans->transid); |
1221 | btrfs_set_header_owner(c, root->root_key.objectid); | 1281 | btrfs_set_header_owner(c, root->root_key.objectid); |
1222 | lower = path->nodes[level-1]; | ||
1223 | 1282 | ||
1224 | write_extent_buffer(c, root->fs_info->fsid, | 1283 | write_extent_buffer(c, root->fs_info->fsid, |
1225 | (unsigned long)btrfs_header_fsid(c), | 1284 | (unsigned long)btrfs_header_fsid(c), |
1226 | BTRFS_FSID_SIZE); | 1285 | BTRFS_FSID_SIZE); |
1227 | if (level == 1) | ||
1228 | btrfs_item_key(lower, &lower_key, 0); | ||
1229 | else | ||
1230 | btrfs_node_key(lower, &lower_key, 0); | ||
1231 | btrfs_set_node_key(c, &lower_key, 0); | 1286 | btrfs_set_node_key(c, &lower_key, 0); |
1232 | btrfs_set_node_blockptr(c, 0, lower->start); | 1287 | btrfs_set_node_blockptr(c, 0, lower->start); |
1233 | WARN_ON(btrfs_header_generation(lower) == 0); | 1288 | lower_gen = btrfs_header_generation(lower); |
1234 | btrfs_set_node_ptr_generation(c, 0, btrfs_header_generation(lower)); | 1289 | WARN_ON(lower_gen == 0); |
1290 | |||
1291 | btrfs_set_node_ptr_generation(c, 0, lower_gen); | ||
1235 | 1292 | ||
1236 | btrfs_mark_buffer_dirty(c); | 1293 | btrfs_mark_buffer_dirty(c); |
1237 | 1294 | ||
@@ -1241,6 +1298,18 @@ static int insert_new_root(struct btrfs_trans_handle *trans, | |||
1241 | extent_buffer_get(c); | 1298 | extent_buffer_get(c); |
1242 | path->nodes[level] = c; | 1299 | path->nodes[level] = c; |
1243 | path->slots[level] = 0; | 1300 | path->slots[level] = 0; |
1301 | |||
1302 | if (root->ref_cows && lower_gen != trans->transid) { | ||
1303 | struct btrfs_path *back_path = btrfs_alloc_path(); | ||
1304 | int ret; | ||
1305 | ret = btrfs_insert_extent_backref(trans, | ||
1306 | root->fs_info->extent_root, | ||
1307 | path, lower->start, | ||
1308 | root->root_key.objectid, | ||
1309 | trans->transid, 0, 0); | ||
1310 | BUG_ON(ret); | ||
1311 | btrfs_free_path(back_path); | ||
1312 | } | ||
1244 | return 0; | 1313 | return 0; |
1245 | } | 1314 | } |
1246 | 1315 | ||
@@ -1294,6 +1363,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1294 | static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | 1363 | static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root |
1295 | *root, struct btrfs_path *path, int level) | 1364 | *root, struct btrfs_path *path, int level) |
1296 | { | 1365 | { |
1366 | u64 root_gen; | ||
1297 | struct extent_buffer *c; | 1367 | struct extent_buffer *c; |
1298 | struct extent_buffer *split; | 1368 | struct extent_buffer *split; |
1299 | struct btrfs_disk_key disk_key; | 1369 | struct btrfs_disk_key disk_key; |
@@ -1303,6 +1373,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1303 | u32 c_nritems; | 1373 | u32 c_nritems; |
1304 | 1374 | ||
1305 | c = path->nodes[level]; | 1375 | c = path->nodes[level]; |
1376 | WARN_ON(btrfs_header_generation(c) != trans->transid); | ||
1306 | if (c == root->node) { | 1377 | if (c == root->node) { |
1307 | /* trying to split the root, lets make a new one */ | 1378 | /* trying to split the root, lets make a new one */ |
1308 | ret = insert_new_root(trans, root, path, level + 1); | 1379 | ret = insert_new_root(trans, root, path, level + 1); |
@@ -1319,8 +1390,17 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1319 | } | 1390 | } |
1320 | 1391 | ||
1321 | c_nritems = btrfs_header_nritems(c); | 1392 | c_nritems = btrfs_header_nritems(c); |
1322 | split = btrfs_alloc_free_block(trans, root, root->nodesize, | 1393 | if (root->ref_cows) |
1323 | c->start, 0); | 1394 | root_gen = trans->transid; |
1395 | else | ||
1396 | root_gen = 0; | ||
1397 | |||
1398 | btrfs_node_key(c, &disk_key, 0); | ||
1399 | split = __btrfs_alloc_free_block(trans, root, root->nodesize, | ||
1400 | root->root_key.objectid, | ||
1401 | root_gen, | ||
1402 | btrfs_disk_key_objectid(&disk_key), | ||
1403 | level, c->start, 0); | ||
1324 | if (IS_ERR(split)) | 1404 | if (IS_ERR(split)) |
1325 | return PTR_ERR(split); | 1405 | return PTR_ERR(split); |
1326 | 1406 | ||
@@ -1789,6 +1869,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1789 | *root, struct btrfs_key *ins_key, | 1869 | *root, struct btrfs_key *ins_key, |
1790 | struct btrfs_path *path, int data_size, int extend) | 1870 | struct btrfs_path *path, int data_size, int extend) |
1791 | { | 1871 | { |
1872 | u64 root_gen; | ||
1792 | struct extent_buffer *l; | 1873 | struct extent_buffer *l; |
1793 | u32 nritems; | 1874 | u32 nritems; |
1794 | int mid; | 1875 | int mid; |
@@ -1807,6 +1888,11 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1807 | if (extend) | 1888 | if (extend) |
1808 | space_needed = data_size; | 1889 | space_needed = data_size; |
1809 | 1890 | ||
1891 | if (root->ref_cows) | ||
1892 | root_gen = trans->transid; | ||
1893 | else | ||
1894 | root_gen = 0; | ||
1895 | |||
1810 | /* first try to make some room by pushing left and right */ | 1896 | /* first try to make some room by pushing left and right */ |
1811 | if (ins_key->type != BTRFS_DIR_ITEM_KEY) { | 1897 | if (ins_key->type != BTRFS_DIR_ITEM_KEY) { |
1812 | wret = push_leaf_right(trans, root, path, data_size, 0); | 1898 | wret = push_leaf_right(trans, root, path, data_size, 0); |
@@ -1837,8 +1923,12 @@ again: | |||
1837 | nritems = btrfs_header_nritems(l); | 1923 | nritems = btrfs_header_nritems(l); |
1838 | mid = (nritems + 1)/ 2; | 1924 | mid = (nritems + 1)/ 2; |
1839 | 1925 | ||
1840 | right = btrfs_alloc_free_block(trans, root, root->leafsize, | 1926 | btrfs_item_key(l, &disk_key, 0); |
1841 | l->start, 0); | 1927 | |
1928 | right = __btrfs_alloc_free_block(trans, root, root->leafsize, | ||
1929 | root->root_key.objectid, | ||
1930 | root_gen, disk_key.objectid, 0, | ||
1931 | l->start, 0); | ||
1842 | if (IS_ERR(right)) | 1932 | if (IS_ERR(right)) |
1843 | return PTR_ERR(right); | 1933 | return PTR_ERR(right); |
1844 | 1934 | ||
@@ -2413,13 +2503,16 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2413 | if (leaf == root->node) { | 2503 | if (leaf == root->node) { |
2414 | btrfs_set_header_level(leaf, 0); | 2504 | btrfs_set_header_level(leaf, 0); |
2415 | } else { | 2505 | } else { |
2506 | u64 root_gen = btrfs_header_generation(path->nodes[1]); | ||
2416 | clean_tree_block(trans, root, leaf); | 2507 | clean_tree_block(trans, root, leaf); |
2417 | wait_on_tree_block_writeback(root, leaf); | 2508 | wait_on_tree_block_writeback(root, leaf); |
2418 | wret = del_ptr(trans, root, path, 1, path->slots[1]); | 2509 | wret = del_ptr(trans, root, path, 1, path->slots[1]); |
2419 | if (wret) | 2510 | if (wret) |
2420 | ret = wret; | 2511 | ret = wret; |
2421 | wret = btrfs_free_extent(trans, root, | 2512 | wret = btrfs_free_extent(trans, root, |
2422 | leaf->start, leaf->len, 1); | 2513 | leaf->start, leaf->len, |
2514 | btrfs_header_owner(path->nodes[1]), | ||
2515 | root_gen, 0, 0, 1); | ||
2423 | if (wret) | 2516 | if (wret) |
2424 | ret = wret; | 2517 | ret = wret; |
2425 | } | 2518 | } |
@@ -2456,9 +2549,13 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2456 | } | 2549 | } |
2457 | 2550 | ||
2458 | if (btrfs_header_nritems(leaf) == 0) { | 2551 | if (btrfs_header_nritems(leaf) == 0) { |
2552 | u64 root_gen; | ||
2459 | u64 bytenr = leaf->start; | 2553 | u64 bytenr = leaf->start; |
2460 | u32 blocksize = leaf->len; | 2554 | u32 blocksize = leaf->len; |
2461 | 2555 | ||
2556 | root_gen = btrfs_header_generation( | ||
2557 | path->nodes[1]); | ||
2558 | |||
2462 | clean_tree_block(trans, root, leaf); | 2559 | clean_tree_block(trans, root, leaf); |
2463 | wait_on_tree_block_writeback(root, leaf); | 2560 | wait_on_tree_block_writeback(root, leaf); |
2464 | 2561 | ||
@@ -2468,7 +2565,9 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2468 | 2565 | ||
2469 | free_extent_buffer(leaf); | 2566 | free_extent_buffer(leaf); |
2470 | wret = btrfs_free_extent(trans, root, bytenr, | 2567 | wret = btrfs_free_extent(trans, root, bytenr, |
2471 | blocksize, 1); | 2568 | blocksize, |
2569 | btrfs_header_owner(path->nodes[1]), | ||
2570 | root_gen, 0, 0, 1); | ||
2472 | if (wret) | 2571 | if (wret) |
2473 | ret = wret; | 2572 | ret = wret; |
2474 | } else { | 2573 | } else { |
@@ -2483,6 +2582,61 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
2483 | } | 2582 | } |
2484 | 2583 | ||
2485 | /* | 2584 | /* |
2585 | * walk up the tree as far as required to find the previous leaf. | ||
2586 | * returns 0 if it found something or 1 if there are no lesser leaves. | ||
2587 | * returns < 0 on io errors. | ||
2588 | */ | ||
2589 | int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) | ||
2590 | { | ||
2591 | int slot; | ||
2592 | int level = 1; | ||
2593 | u64 bytenr; | ||
2594 | struct extent_buffer *c; | ||
2595 | struct extent_buffer *next = NULL; | ||
2596 | |||
2597 | while(level < BTRFS_MAX_LEVEL) { | ||
2598 | if (!path->nodes[level]) | ||
2599 | return 1; | ||
2600 | |||
2601 | slot = path->slots[level]; | ||
2602 | c = path->nodes[level]; | ||
2603 | if (slot == 0) { | ||
2604 | level++; | ||
2605 | if (level == BTRFS_MAX_LEVEL) | ||
2606 | return 1; | ||
2607 | continue; | ||
2608 | } | ||
2609 | slot--; | ||
2610 | |||
2611 | bytenr = btrfs_node_blockptr(c, slot); | ||
2612 | if (next) | ||
2613 | free_extent_buffer(next); | ||
2614 | |||
2615 | if (path->reada < 0) | ||
2616 | reada_for_search(root, path, level, slot); | ||
2617 | |||
2618 | next = read_tree_block(root, bytenr, | ||
2619 | btrfs_level_size(root, level - 1)); | ||
2620 | break; | ||
2621 | } | ||
2622 | path->slots[level] = slot; | ||
2623 | while(1) { | ||
2624 | level--; | ||
2625 | c = path->nodes[level]; | ||
2626 | free_extent_buffer(c); | ||
2627 | path->nodes[level] = next; | ||
2628 | path->slots[level] = 0; | ||
2629 | if (!level) | ||
2630 | break; | ||
2631 | if (path->reada) | ||
2632 | reada_for_search(root, path, level, 0); | ||
2633 | next = read_tree_block(root, btrfs_node_blockptr(next, 0), | ||
2634 | btrfs_level_size(root, level - 1)); | ||
2635 | } | ||
2636 | return 0; | ||
2637 | } | ||
2638 | |||
2639 | /* | ||
2486 | * walk up the tree as far as required to find the next leaf. | 2640 | * walk up the tree as far as required to find the next leaf. |
2487 | * returns 0 if it found something or 1 if there are no greater leaves. | 2641 | * returns 0 if it found something or 1 if there are no greater leaves. |
2488 | * returns < 0 on io errors. | 2642 | * returns < 0 on io errors. |
@@ -2503,6 +2657,8 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
2503 | c = path->nodes[level]; | 2657 | c = path->nodes[level]; |
2504 | if (slot >= btrfs_header_nritems(c)) { | 2658 | if (slot >= btrfs_header_nritems(c)) { |
2505 | level++; | 2659 | level++; |
2660 | if (level == BTRFS_MAX_LEVEL) | ||
2661 | return 1; | ||
2506 | continue; | 2662 | continue; |
2507 | } | 2663 | } |
2508 | 2664 | ||