aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-04-25 16:23:32 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-05-06 15:55:21 -0400
commit3650860b90cc2a06cb9d7e37df005736c46ce87e (patch)
tree7d13260873c76e3a8a6c47eaf737327e0de90a23 /fs/btrfs/tree-log.c
parentb50c6e250ef91313518dbca96663578237ba8d3c (diff)
Btrfs: remove almost all of the BUG()'s from tree-log.c
There were a whole bunch and I was doing it for other things. I haven't tested these error paths but at the very least this is better than panicing. I've only left 2 BUG_ON()'s since they are logic errors and I want to replace them with a ASSERT framework that we can compile out for production users. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c151
1 files changed, 98 insertions, 53 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index aebfb2d7b7d2..705aee6bd15b 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -589,7 +589,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
589 589
590 /* drop any overlapping extents */ 590 /* drop any overlapping extents */
591 ret = btrfs_drop_extents(trans, root, inode, start, extent_end, 1); 591 ret = btrfs_drop_extents(trans, root, inode, start, extent_end, 1);
592 BUG_ON(ret); 592 if (ret)
593 goto out;
593 594
594 if (found_type == BTRFS_FILE_EXTENT_REG || 595 if (found_type == BTRFS_FILE_EXTENT_REG ||
595 found_type == BTRFS_FILE_EXTENT_PREALLOC) { 596 found_type == BTRFS_FILE_EXTENT_PREALLOC) {
@@ -599,7 +600,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
599 600
600 ret = btrfs_insert_empty_item(trans, root, path, key, 601 ret = btrfs_insert_empty_item(trans, root, path, key,
601 sizeof(*item)); 602 sizeof(*item));
602 BUG_ON(ret); 603 if (ret)
604 goto out;
603 dest_offset = btrfs_item_ptr_offset(path->nodes[0], 605 dest_offset = btrfs_item_ptr_offset(path->nodes[0],
604 path->slots[0]); 606 path->slots[0]);
605 copy_extent_buffer(path->nodes[0], eb, dest_offset, 607 copy_extent_buffer(path->nodes[0], eb, dest_offset,
@@ -653,26 +655,30 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
653 ret = btrfs_lookup_csums_range(root->log_root, 655 ret = btrfs_lookup_csums_range(root->log_root,
654 csum_start, csum_end - 1, 656 csum_start, csum_end - 1,
655 &ordered_sums, 0); 657 &ordered_sums, 0);
656 BUG_ON(ret); 658 if (ret)
659 goto out;
657 while (!list_empty(&ordered_sums)) { 660 while (!list_empty(&ordered_sums)) {
658 struct btrfs_ordered_sum *sums; 661 struct btrfs_ordered_sum *sums;
659 sums = list_entry(ordered_sums.next, 662 sums = list_entry(ordered_sums.next,
660 struct btrfs_ordered_sum, 663 struct btrfs_ordered_sum,
661 list); 664 list);
662 ret = btrfs_csum_file_blocks(trans, 665 if (!ret)
666 ret = btrfs_csum_file_blocks(trans,
663 root->fs_info->csum_root, 667 root->fs_info->csum_root,
664 sums); 668 sums);
665 BUG_ON(ret);
666 list_del(&sums->list); 669 list_del(&sums->list);
667 kfree(sums); 670 kfree(sums);
668 } 671 }
672 if (ret)
673 goto out;
669 } else { 674 } else {
670 btrfs_release_path(path); 675 btrfs_release_path(path);
671 } 676 }
672 } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { 677 } else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
673 /* inline extents are easy, we just overwrite them */ 678 /* inline extents are easy, we just overwrite them */
674 ret = overwrite_item(trans, root, path, eb, slot, key); 679 ret = overwrite_item(trans, root, path, eb, slot, key);
675 BUG_ON(ret); 680 if (ret)
681 goto out;
676 } 682 }
677 683
678 inode_add_bytes(inode, nbytes); 684 inode_add_bytes(inode, nbytes);
@@ -717,20 +723,21 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans,
717 723
718 inode = read_one_inode(root, location.objectid); 724 inode = read_one_inode(root, location.objectid);
719 if (!inode) { 725 if (!inode) {
720 kfree(name); 726 ret = -EIO;
721 return -EIO; 727 goto out;
722 } 728 }
723 729
724 ret = link_to_fixup_dir(trans, root, path, location.objectid); 730 ret = link_to_fixup_dir(trans, root, path, location.objectid);
725 BUG_ON(ret); 731 if (ret)
732 goto out;
726 733
727 ret = btrfs_unlink_inode(trans, root, dir, inode, name, name_len); 734 ret = btrfs_unlink_inode(trans, root, dir, inode, name, name_len);
728 BUG_ON(ret); 735 if (ret)
736 goto out;
737 btrfs_run_delayed_items(trans, root);
738out:
729 kfree(name); 739 kfree(name);
730
731 iput(inode); 740 iput(inode);
732
733 btrfs_run_delayed_items(trans, root);
734 return ret; 741 return ret;
735} 742}
736 743
@@ -883,7 +890,8 @@ again:
883 victim_name_len = btrfs_inode_ref_name_len(leaf, 890 victim_name_len = btrfs_inode_ref_name_len(leaf,
884 victim_ref); 891 victim_ref);
885 victim_name = kmalloc(victim_name_len, GFP_NOFS); 892 victim_name = kmalloc(victim_name_len, GFP_NOFS);
886 BUG_ON(!victim_name); 893 if (!victim_name)
894 return -ENOMEM;
887 895
888 read_extent_buffer(leaf, victim_name, 896 read_extent_buffer(leaf, victim_name,
889 (unsigned long)(victim_ref + 1), 897 (unsigned long)(victim_ref + 1),
@@ -899,9 +907,10 @@ again:
899 ret = btrfs_unlink_inode(trans, root, dir, 907 ret = btrfs_unlink_inode(trans, root, dir,
900 inode, victim_name, 908 inode, victim_name,
901 victim_name_len); 909 victim_name_len);
902 BUG_ON(ret);
903 btrfs_run_delayed_items(trans, root);
904 kfree(victim_name); 910 kfree(victim_name);
911 if (ret)
912 return ret;
913 btrfs_run_delayed_items(trans, root);
905 *search_done = 1; 914 *search_done = 1;
906 goto again; 915 goto again;
907 } 916 }
@@ -909,7 +918,6 @@ again:
909 918
910 ptr = (unsigned long)(victim_ref + 1) + victim_name_len; 919 ptr = (unsigned long)(victim_ref + 1) + victim_name_len;
911 } 920 }
912 BUG_ON(ret);
913 921
914 /* 922 /*
915 * NOTE: we have searched root tree and checked the 923 * NOTE: we have searched root tree and checked the
@@ -943,6 +951,8 @@ again:
943 goto next; 951 goto next;
944 952
945 victim_name = kmalloc(victim_name_len, GFP_NOFS); 953 victim_name = kmalloc(victim_name_len, GFP_NOFS);
954 if (!victim_name)
955 return -ENOMEM;
946 read_extent_buffer(leaf, victim_name, (unsigned long)&extref->name, 956 read_extent_buffer(leaf, victim_name, (unsigned long)&extref->name,
947 victim_name_len); 957 victim_name_len);
948 958
@@ -969,14 +979,16 @@ again:
969 victim_name_len); 979 victim_name_len);
970 btrfs_run_delayed_items(trans, root); 980 btrfs_run_delayed_items(trans, root);
971 } 981 }
972 BUG_ON(ret);
973 iput(victim_parent); 982 iput(victim_parent);
974 kfree(victim_name); 983 kfree(victim_name);
984 if (ret)
985 return ret;
975 *search_done = 1; 986 *search_done = 1;
976 goto again; 987 goto again;
977 } 988 }
978 kfree(victim_name); 989 kfree(victim_name);
979 BUG_ON(ret); 990 if (ret)
991 return ret;
980next: 992next:
981 cur_offset += victim_name_len + sizeof(*extref); 993 cur_offset += victim_name_len + sizeof(*extref);
982 } 994 }
@@ -989,7 +1001,8 @@ next:
989 ref_index, name, namelen, 0); 1001 ref_index, name, namelen, 0);
990 if (di && !IS_ERR(di)) { 1002 if (di && !IS_ERR(di)) {
991 ret = drop_one_dir_item(trans, root, path, dir, di); 1003 ret = drop_one_dir_item(trans, root, path, dir, di);
992 BUG_ON(ret); 1004 if (ret)
1005 return ret;
993 } 1006 }
994 btrfs_release_path(path); 1007 btrfs_release_path(path);
995 1008
@@ -998,7 +1011,8 @@ next:
998 name, namelen, 0); 1011 name, namelen, 0);
999 if (di && !IS_ERR(di)) { 1012 if (di && !IS_ERR(di)) {
1000 ret = drop_one_dir_item(trans, root, path, dir, di); 1013 ret = drop_one_dir_item(trans, root, path, dir, di);
1001 BUG_ON(ret); 1014 if (ret)
1015 return ret;
1002 } 1016 }
1003 btrfs_release_path(path); 1017 btrfs_release_path(path);
1004 1018
@@ -1143,15 +1157,19 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
1143 parent_objectid, 1157 parent_objectid,
1144 ref_index, name, namelen, 1158 ref_index, name, namelen,
1145 &search_done); 1159 &search_done);
1146 if (ret == 1) 1160 if (ret == 1) {
1161 ret = 0;
1162 goto out;
1163 }
1164 if (ret)
1147 goto out; 1165 goto out;
1148 BUG_ON(ret);
1149 } 1166 }
1150 1167
1151 /* insert our name */ 1168 /* insert our name */
1152 ret = btrfs_add_link(trans, dir, inode, name, namelen, 1169 ret = btrfs_add_link(trans, dir, inode, name, namelen,
1153 0, ref_index); 1170 0, ref_index);
1154 BUG_ON(ret); 1171 if (ret)
1172 goto out;
1155 1173
1156 btrfs_update_inode(trans, root, inode); 1174 btrfs_update_inode(trans, root, inode);
1157 } 1175 }
@@ -1166,13 +1184,11 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
1166 1184
1167 /* finally write the back reference in the inode */ 1185 /* finally write the back reference in the inode */
1168 ret = overwrite_item(trans, root, path, eb, slot, key); 1186 ret = overwrite_item(trans, root, path, eb, slot, key);
1169 BUG_ON(ret);
1170
1171out: 1187out:
1172 btrfs_release_path(path); 1188 btrfs_release_path(path);
1173 iput(dir); 1189 iput(dir);
1174 iput(inode); 1190 iput(inode);
1175 return 0; 1191 return ret;
1176} 1192}
1177 1193
1178static int insert_orphan_item(struct btrfs_trans_handle *trans, 1194static int insert_orphan_item(struct btrfs_trans_handle *trans,
@@ -1330,10 +1346,10 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
1330 if (S_ISDIR(inode->i_mode)) { 1346 if (S_ISDIR(inode->i_mode)) {
1331 ret = replay_dir_deletes(trans, root, NULL, path, 1347 ret = replay_dir_deletes(trans, root, NULL, path,
1332 ino, 1); 1348 ino, 1);
1333 BUG_ON(ret); 1349 if (ret)
1350 goto out;
1334 } 1351 }
1335 ret = insert_orphan_item(trans, root, ino); 1352 ret = insert_orphan_item(trans, root, ino);
1336 BUG_ON(ret);
1337 } 1353 }
1338 1354
1339out: 1355out:
@@ -1378,9 +1394,9 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans,
1378 return -EIO; 1394 return -EIO;
1379 1395
1380 ret = fixup_inode_link_count(trans, root, inode); 1396 ret = fixup_inode_link_count(trans, root, inode);
1381 BUG_ON(ret);
1382
1383 iput(inode); 1397 iput(inode);
1398 if (ret)
1399 goto out;
1384 1400
1385 /* 1401 /*
1386 * fixup on a directory may create new entries, 1402 * fixup on a directory may create new entries,
@@ -1430,7 +1446,7 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans,
1430 } else if (ret == -EEXIST) { 1446 } else if (ret == -EEXIST) {
1431 ret = 0; 1447 ret = 0;
1432 } else { 1448 } else {
1433 BUG(); 1449 BUG(); /* Logic Error */
1434 } 1450 }
1435 iput(inode); 1451 iput(inode);
1436 1452
@@ -1499,7 +1515,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
1499 struct inode *dir; 1515 struct inode *dir;
1500 u8 log_type; 1516 u8 log_type;
1501 int exists; 1517 int exists;
1502 int ret; 1518 int ret = 0;
1503 1519
1504 dir = read_one_inode(root, key->objectid); 1520 dir = read_one_inode(root, key->objectid);
1505 if (!dir) 1521 if (!dir)
@@ -1531,7 +1547,9 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
1531 key->offset, name, 1547 key->offset, name,
1532 name_len, 1); 1548 name_len, 1);
1533 } else { 1549 } else {
1534 BUG(); 1550 /* Corruption */
1551 ret = -EINVAL;
1552 goto out;
1535 } 1553 }
1536 if (IS_ERR_OR_NULL(dst_di)) { 1554 if (IS_ERR_OR_NULL(dst_di)) {
1537 /* we need a sequence number to insert, so we only 1555 /* we need a sequence number to insert, so we only
@@ -1559,7 +1577,8 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
1559 goto out; 1577 goto out;
1560 1578
1561 ret = drop_one_dir_item(trans, root, path, dir, dst_di); 1579 ret = drop_one_dir_item(trans, root, path, dir, dst_di);
1562 BUG_ON(ret); 1580 if (ret)
1581 goto out;
1563 1582
1564 if (key->type == BTRFS_DIR_INDEX_KEY) 1583 if (key->type == BTRFS_DIR_INDEX_KEY)
1565 goto insert; 1584 goto insert;
@@ -1567,14 +1586,15 @@ out:
1567 btrfs_release_path(path); 1586 btrfs_release_path(path);
1568 kfree(name); 1587 kfree(name);
1569 iput(dir); 1588 iput(dir);
1570 return 0; 1589 return ret;
1571 1590
1572insert: 1591insert:
1573 btrfs_release_path(path); 1592 btrfs_release_path(path);
1574 ret = insert_one_name(trans, root, path, key->objectid, key->offset, 1593 ret = insert_one_name(trans, root, path, key->objectid, key->offset,
1575 name, name_len, log_type, &log_key); 1594 name, name_len, log_type, &log_key);
1576 1595 if (ret && ret != -ENOENT)
1577 BUG_ON(ret && ret != -ENOENT); 1596 goto out;
1597 ret = 0;
1578 goto out; 1598 goto out;
1579} 1599}
1580 1600
@@ -1605,7 +1625,8 @@ static noinline int replay_one_dir_item(struct btrfs_trans_handle *trans,
1605 return -EIO; 1625 return -EIO;
1606 name_len = btrfs_dir_name_len(eb, di); 1626 name_len = btrfs_dir_name_len(eb, di);
1607 ret = replay_one_name(trans, root, path, eb, di, key); 1627 ret = replay_one_name(trans, root, path, eb, di, key);
1608 BUG_ON(ret); 1628 if (ret)
1629 return ret;
1609 ptr = (unsigned long)(di + 1); 1630 ptr = (unsigned long)(di + 1);
1610 ptr += name_len; 1631 ptr += name_len;
1611 } 1632 }
@@ -1766,16 +1787,21 @@ again:
1766 1787
1767 ret = link_to_fixup_dir(trans, root, 1788 ret = link_to_fixup_dir(trans, root,
1768 path, location.objectid); 1789 path, location.objectid);
1769 BUG_ON(ret); 1790 if (ret) {
1791 kfree(name);
1792 iput(inode);
1793 goto out;
1794 }
1795
1770 btrfs_inc_nlink(inode); 1796 btrfs_inc_nlink(inode);
1771 ret = btrfs_unlink_inode(trans, root, dir, inode, 1797 ret = btrfs_unlink_inode(trans, root, dir, inode,
1772 name, name_len); 1798 name, name_len);
1773 BUG_ON(ret); 1799 if (!ret)
1774 1800 btrfs_run_delayed_items(trans, root);
1775 btrfs_run_delayed_items(trans, root);
1776
1777 kfree(name); 1801 kfree(name);
1778 iput(inode); 1802 iput(inode);
1803 if (ret)
1804 goto out;
1779 1805
1780 /* there might still be more names under this key 1806 /* there might still be more names under this key
1781 * check and repeat if required 1807 * check and repeat if required
@@ -1879,7 +1905,8 @@ again:
1879 ret = check_item_in_log(trans, root, log, path, 1905 ret = check_item_in_log(trans, root, log, path,
1880 log_path, dir, 1906 log_path, dir,
1881 &found_key); 1907 &found_key);
1882 BUG_ON(ret); 1908 if (ret)
1909 goto out;
1883 if (found_key.offset == (u64)-1) 1910 if (found_key.offset == (u64)-1)
1884 break; 1911 break;
1885 dir_key.offset = found_key.offset + 1; 1912 dir_key.offset = found_key.offset + 1;
@@ -2083,7 +2110,10 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
2083 BTRFS_TREE_LOG_OBJECTID); 2110 BTRFS_TREE_LOG_OBJECTID);
2084 ret = btrfs_free_and_pin_reserved_extent(root, 2111 ret = btrfs_free_and_pin_reserved_extent(root,
2085 bytenr, blocksize); 2112 bytenr, blocksize);
2086 BUG_ON(ret); /* -ENOMEM or logic errors */ 2113 if (ret) {
2114 free_extent_buffer(next);
2115 return ret;
2116 }
2087 } 2117 }
2088 free_extent_buffer(next); 2118 free_extent_buffer(next);
2089 continue; 2119 continue;
@@ -2156,7 +2186,8 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
2156 ret = btrfs_free_and_pin_reserved_extent(root, 2186 ret = btrfs_free_and_pin_reserved_extent(root,
2157 path->nodes[*level]->start, 2187 path->nodes[*level]->start,
2158 path->nodes[*level]->len); 2188 path->nodes[*level]->len);
2159 BUG_ON(ret); 2189 if (ret)
2190 return ret;
2160 } 2191 }
2161 free_extent_buffer(path->nodes[*level]); 2192 free_extent_buffer(path->nodes[*level]);
2162 path->nodes[*level] = NULL; 2193 path->nodes[*level] = NULL;
@@ -2229,7 +2260,8 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
2229 BTRFS_TREE_LOG_OBJECTID); 2260 BTRFS_TREE_LOG_OBJECTID);
2230 ret = btrfs_free_and_pin_reserved_extent(log, next->start, 2261 ret = btrfs_free_and_pin_reserved_extent(log, next->start,
2231 next->len); 2262 next->len);
2232 BUG_ON(ret); /* -ENOMEM or logic errors */ 2263 if (ret)
2264 goto out;
2233 } 2265 }
2234 } 2266 }
2235 2267
@@ -2517,7 +2549,10 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
2517 2549
2518 if (trans) { 2550 if (trans) {
2519 ret = walk_log_tree(trans, log, &wc); 2551 ret = walk_log_tree(trans, log, &wc);
2520 BUG_ON(ret); 2552
2553 /* I don't think this can happen but just in case */
2554 if (ret)
2555 btrfs_abort_transaction(trans, log, ret);
2521 } 2556 }
2522 2557
2523 while (1) { 2558 while (1) {
@@ -2625,7 +2660,10 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
2625 if (di) { 2660 if (di) {
2626 ret = btrfs_delete_one_dir_name(trans, log, path, di); 2661 ret = btrfs_delete_one_dir_name(trans, log, path, di);
2627 bytes_del += name_len; 2662 bytes_del += name_len;
2628 BUG_ON(ret); 2663 if (ret) {
2664 err = ret;
2665 goto fail;
2666 }
2629 } 2667 }
2630 btrfs_release_path(path); 2668 btrfs_release_path(path);
2631 di = btrfs_lookup_dir_index_item(trans, log, path, dir_ino, 2669 di = btrfs_lookup_dir_index_item(trans, log, path, dir_ino,
@@ -2637,7 +2675,10 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
2637 if (di) { 2675 if (di) {
2638 ret = btrfs_delete_one_dir_name(trans, log, path, di); 2676 ret = btrfs_delete_one_dir_name(trans, log, path, di);
2639 bytes_del += name_len; 2677 bytes_del += name_len;
2640 BUG_ON(ret); 2678 if (ret) {
2679 err = ret;
2680 goto fail;
2681 }
2641 } 2682 }
2642 2683
2643 /* update the directory size in the log to reflect the names 2684 /* update the directory size in the log to reflect the names
@@ -2976,7 +3017,7 @@ static int drop_objectid_items(struct btrfs_trans_handle *trans,
2976 3017
2977 while (1) { 3018 while (1) {
2978 ret = btrfs_search_slot(trans, log, &key, path, -1, 1); 3019 ret = btrfs_search_slot(trans, log, &key, path, -1, 1);
2979 BUG_ON(ret == 0); 3020 BUG_ON(ret == 0); /* Logic error */
2980 if (ret < 0) 3021 if (ret < 0)
2981 break; 3022 break;
2982 3023
@@ -3179,7 +3220,11 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3179 log->fs_info->csum_root, 3220 log->fs_info->csum_root,
3180 ds + cs, ds + cs + cl - 1, 3221 ds + cs, ds + cs + cl - 1,
3181 &ordered_sums, 0); 3222 &ordered_sums, 0);
3182 BUG_ON(ret); 3223 if (ret) {
3224 btrfs_release_path(dst_path);
3225 kfree(ins_data);
3226 return ret;
3227 }
3183 } 3228 }
3184 } 3229 }
3185 } 3230 }