aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c66
1 files changed, 40 insertions, 26 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index afa5bc5c7c1a..57fa505fb9f6 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -250,6 +250,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
250 tree_block_release(root, mid_buf); 250 tree_block_release(root, mid_buf);
251 /* once for the root ptr */ 251 /* once for the root ptr */
252 tree_block_release(root, mid_buf); 252 tree_block_release(root, mid_buf);
253 clean_tree_block(root, mid_buf);
253 return free_extent(root, blocknr, 1); 254 return free_extent(root, blocknr, 1);
254 } 255 }
255 parent = &parent_buf->node; 256 parent = &parent_buf->node;
@@ -280,6 +281,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
280 if (right->header.nritems == 0) { 281 if (right->header.nritems == 0) {
281 u64 blocknr = right_buf->blocknr; 282 u64 blocknr = right_buf->blocknr;
282 tree_block_release(root, right_buf); 283 tree_block_release(root, right_buf);
284 clean_tree_block(root, right_buf);
283 right_buf = NULL; 285 right_buf = NULL;
284 right = NULL; 286 right = NULL;
285 wret = del_ptr(root, path, level + 1, pslot + 1); 287 wret = del_ptr(root, path, level + 1, pslot + 1);
@@ -291,7 +293,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
291 } else { 293 } else {
292 memcpy(parent->keys + pslot + 1, right->keys, 294 memcpy(parent->keys + pslot + 1, right->keys,
293 sizeof(struct key)); 295 sizeof(struct key));
294 wret = write_tree_block(root, parent_buf); 296 wret = dirty_tree_block(root, parent_buf);
295 if (wret) 297 if (wret)
296 ret = wret; 298 ret = wret;
297 } 299 }
@@ -316,6 +318,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
316 /* we've managed to empty the middle node, drop it */ 318 /* we've managed to empty the middle node, drop it */
317 u64 blocknr = mid_buf->blocknr; 319 u64 blocknr = mid_buf->blocknr;
318 tree_block_release(root, mid_buf); 320 tree_block_release(root, mid_buf);
321 clean_tree_block(root, mid_buf);
319 mid_buf = NULL; 322 mid_buf = NULL;
320 mid = NULL; 323 mid = NULL;
321 wret = del_ptr(root, path, level + 1, pslot); 324 wret = del_ptr(root, path, level + 1, pslot);
@@ -327,7 +330,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
327 } else { 330 } else {
328 /* update the parent key to reflect our changes */ 331 /* update the parent key to reflect our changes */
329 memcpy(parent->keys + pslot, mid->keys, sizeof(struct key)); 332 memcpy(parent->keys + pslot, mid->keys, sizeof(struct key));
330 wret = write_tree_block(root, parent_buf); 333 wret = dirty_tree_block(root, parent_buf);
331 if (wret) 334 if (wret)
332 ret = wret; 335 ret = wret;
333 } 336 }
@@ -458,7 +461,7 @@ static int fixup_low_keys(struct ctree_root *root,
458 break; 461 break;
459 t = &path->nodes[i]->node; 462 t = &path->nodes[i]->node;
460 memcpy(t->keys + tslot, key, sizeof(*key)); 463 memcpy(t->keys + tslot, key, sizeof(*key));
461 wret = write_tree_block(root, path->nodes[i]); 464 wret = dirty_tree_block(root, path->nodes[i]);
462 if (wret) 465 if (wret)
463 ret = wret; 466 ret = wret;
464 if (tslot != 0) 467 if (tslot != 0)
@@ -508,11 +511,11 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf,
508 src->header.nritems -= push_items; 511 src->header.nritems -= push_items;
509 dst->header.nritems += push_items; 512 dst->header.nritems += push_items;
510 513
511 wret = write_tree_block(root, src_buf); 514 wret = dirty_tree_block(root, src_buf);
512 if (wret < 0) 515 if (wret < 0)
513 ret = wret; 516 ret = wret;
514 517
515 wret = write_tree_block(root, dst_buf); 518 wret = dirty_tree_block(root, dst_buf);
516 if (wret < 0) 519 if (wret < 0)
517 ret = wret; 520 ret = wret;
518 return ret; 521 return ret;
@@ -566,11 +569,11 @@ static int balance_node_right(struct ctree_root *root,
566 src->header.nritems -= push_items; 569 src->header.nritems -= push_items;
567 dst->header.nritems += push_items; 570 dst->header.nritems += push_items;
568 571
569 wret = write_tree_block(root, src_buf); 572 wret = dirty_tree_block(root, src_buf);
570 if (wret < 0) 573 if (wret < 0)
571 ret = wret; 574 ret = wret;
572 575
573 wret = write_tree_block(root, dst_buf); 576 wret = dirty_tree_block(root, dst_buf);
574 if (wret < 0) 577 if (wret < 0)
575 ret = wret; 578 ret = wret;
576 return ret; 579 return ret;
@@ -612,7 +615,7 @@ static int insert_new_root(struct ctree_root *root,
612 tree_block_release(root, root->node); 615 tree_block_release(root, root->node);
613 root->node = t; 616 root->node = t;
614 t->count++; 617 t->count++;
615 write_tree_block(root, t); 618 dirty_tree_block(root, t);
616 path->nodes[level] = t; 619 path->nodes[level] = t;
617 path->slots[level] = 0; 620 path->slots[level] = 0;
618 return 0; 621 return 0;
@@ -652,7 +655,7 @@ static int insert_ptr(struct ctree_root *root,
652 lower->header.nritems++; 655 lower->header.nritems++;
653 if (lower->keys[1].objectid == 0) 656 if (lower->keys[1].objectid == 0)
654 BUG(); 657 BUG();
655 write_tree_block(root, path->nodes[level]); 658 dirty_tree_block(root, path->nodes[level]);
656 return 0; 659 return 0;
657} 660}
658 661
@@ -698,10 +701,10 @@ static int split_node(struct ctree_root *root, struct ctree_path *path,
698 c->header.nritems = mid; 701 c->header.nritems = mid;
699 ret = 0; 702 ret = 0;
700 703
701 wret = write_tree_block(root, t); 704 wret = dirty_tree_block(root, t);
702 if (wret) 705 if (wret)
703 ret = wret; 706 ret = wret;
704 wret = write_tree_block(root, split_buffer); 707 wret = dirty_tree_block(root, split_buffer);
705 if (wret) 708 if (wret)
706 ret = wret; 709 ret = wret;
707 wret = insert_ptr(root, path, split->keys, split_buffer->blocknr, 710 wret = insert_ptr(root, path, split->keys, split_buffer->blocknr,
@@ -815,11 +818,11 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
815 } 818 }
816 left->header.nritems -= push_items; 819 left->header.nritems -= push_items;
817 820
818 write_tree_block(root, left_buf); 821 dirty_tree_block(root, left_buf);
819 write_tree_block(root, right_buf); 822 dirty_tree_block(root, right_buf);
820 memcpy(upper->node.keys + slot + 1, 823 memcpy(upper->node.keys + slot + 1,
821 &right->items[0].key, sizeof(struct key)); 824 &right->items[0].key, sizeof(struct key));
822 write_tree_block(root, upper); 825 dirty_tree_block(root, upper);
823 /* then fixup the leaf pointer in the path */ 826 /* then fixup the leaf pointer in the path */
824 if (path->slots[0] >= left->header.nritems) { 827 if (path->slots[0] >= left->header.nritems) {
825 path->slots[0] -= left->header.nritems; 828 path->slots[0] -= left->header.nritems;
@@ -909,10 +912,10 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
909 push_space = right->items[i].offset; 912 push_space = right->items[i].offset;
910 } 913 }
911 914
912 wret = write_tree_block(root, t); 915 wret = dirty_tree_block(root, t);
913 if (wret) 916 if (wret)
914 ret = wret; 917 ret = wret;
915 wret = write_tree_block(root, right_buf); 918 wret = dirty_tree_block(root, right_buf);
916 if (wret) 919 if (wret)
917 ret = wret; 920 ret = wret;
918 921
@@ -1019,10 +1022,10 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
1019 right_buffer->blocknr, path->slots[1] + 1, 1); 1022 right_buffer->blocknr, path->slots[1] + 1, 1);
1020 if (wret) 1023 if (wret)
1021 ret = wret; 1024 ret = wret;
1022 wret = write_tree_block(root, right_buffer); 1025 wret = dirty_tree_block(root, right_buffer);
1023 if (wret) 1026 if (wret)
1024 ret = wret; 1027 ret = wret;
1025 wret = write_tree_block(root, l_buf); 1028 wret = dirty_tree_block(root, l_buf);
1026 if (wret) 1029 if (wret)
1027 ret = wret; 1030 ret = wret;
1028 1031
@@ -1062,12 +1065,14 @@ int insert_item(struct ctree_root *root, struct key *key,
1062 ret = search_slot(root, key, &path, data_size); 1065 ret = search_slot(root, key, &path, data_size);
1063 if (ret == 0) { 1066 if (ret == 0) {
1064 release_path(root, &path); 1067 release_path(root, &path);
1065 return -EEXIST; 1068 ret = -EEXIST;
1066 } 1069 wret = commit_transaction(root);
1067 if (ret < 0) { 1070 if (wret)
1068 release_path(root, &path); 1071 ret = wret;
1069 return ret; 1072 return ret;
1070 } 1073 }
1074 if (ret < 0)
1075 goto out;
1071 1076
1072 slot_orig = path.slots[0]; 1077 slot_orig = path.slots[0];
1073 leaf_buf = path.nodes[0]; 1078 leaf_buf = path.nodes[0];
@@ -1113,14 +1118,18 @@ int insert_item(struct ctree_root *root, struct key *key,
1113 if (slot == 0) 1118 if (slot == 0)
1114 ret = fixup_low_keys(root, &path, key, 1); 1119 ret = fixup_low_keys(root, &path, key, 1);
1115 1120
1116 wret = write_tree_block(root, leaf_buf); 1121 wret = dirty_tree_block(root, leaf_buf);
1117 if (wret) 1122 if (wret)
1118 ret = wret; 1123 ret = wret;
1119 1124
1120 if (leaf_free_space(leaf) < 0) 1125 if (leaf_free_space(leaf) < 0)
1121 BUG(); 1126 BUG();
1122 check_leaf(&path, 0); 1127 check_leaf(&path, 0);
1128out:
1123 release_path(root, &path); 1129 release_path(root, &path);
1130 wret = commit_transaction(root);
1131 if (wret)
1132 ret = wret;
1124 return ret; 1133 return ret;
1125} 1134}
1126 1135
@@ -1160,7 +1169,7 @@ static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level,
1160 if (wret) 1169 if (wret)
1161 ret = wret; 1170 ret = wret;
1162 } 1171 }
1163 wret = write_tree_block(root, parent); 1172 wret = dirty_tree_block(root, parent);
1164 if (wret) 1173 if (wret)
1165 ret = wret; 1174 ret = wret;
1166 return ret; 1175 return ret;
@@ -1203,8 +1212,9 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
1203 if (leaf->header.nritems == 0) { 1212 if (leaf->header.nritems == 0) {
1204 if (leaf_buf == root->node) { 1213 if (leaf_buf == root->node) {
1205 leaf->header.flags = node_level(0); 1214 leaf->header.flags = node_level(0);
1206 write_tree_block(root, leaf_buf); 1215 dirty_tree_block(root, leaf_buf);
1207 } else { 1216 } else {
1217 clean_tree_block(root, leaf_buf);
1208 wret = del_ptr(root, path, 1, path->slots[1]); 1218 wret = del_ptr(root, path, 1, path->slots[1]);
1209 if (wret) 1219 if (wret)
1210 ret = wret; 1220 ret = wret;
@@ -1220,7 +1230,7 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
1220 if (wret) 1230 if (wret)
1221 ret = wret; 1231 ret = wret;
1222 } 1232 }
1223 wret = write_tree_block(root, leaf_buf); 1233 wret = dirty_tree_block(root, leaf_buf);
1224 if (wret) 1234 if (wret)
1225 ret = wret; 1235 ret = wret;
1226 1236
@@ -1242,6 +1252,7 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
1242 } 1252 }
1243 if (leaf->header.nritems == 0) { 1253 if (leaf->header.nritems == 0) {
1244 u64 blocknr = leaf_buf->blocknr; 1254 u64 blocknr = leaf_buf->blocknr;
1255 clean_tree_block(root, leaf_buf);
1245 wret = del_ptr(root, path, 1, slot); 1256 wret = del_ptr(root, path, 1, slot);
1246 if (wret) 1257 if (wret)
1247 ret = wret; 1258 ret = wret;
@@ -1254,6 +1265,9 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
1254 } 1265 }
1255 } 1266 }
1256 } 1267 }
1268 wret = commit_transaction(root);
1269 if (wret)
1270 ret = wret;
1257 return ret; 1271 return ret;
1258} 1272}
1259 1273