提交 3650860b 编写于 作者: J Josef Bacik

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: NJosef Bacik <jbacik@fusionio.com>
上级 b50c6e25
...@@ -589,7 +589,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, ...@@ -589,7 +589,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
/* drop any overlapping extents */ /* drop any overlapping extents */
ret = btrfs_drop_extents(trans, root, inode, start, extent_end, 1); ret = btrfs_drop_extents(trans, root, inode, start, extent_end, 1);
BUG_ON(ret); if (ret)
goto out;
if (found_type == BTRFS_FILE_EXTENT_REG || if (found_type == BTRFS_FILE_EXTENT_REG ||
found_type == BTRFS_FILE_EXTENT_PREALLOC) { found_type == BTRFS_FILE_EXTENT_PREALLOC) {
...@@ -599,7 +600,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, ...@@ -599,7 +600,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
ret = btrfs_insert_empty_item(trans, root, path, key, ret = btrfs_insert_empty_item(trans, root, path, key,
sizeof(*item)); sizeof(*item));
BUG_ON(ret); if (ret)
goto out;
dest_offset = btrfs_item_ptr_offset(path->nodes[0], dest_offset = btrfs_item_ptr_offset(path->nodes[0],
path->slots[0]); path->slots[0]);
copy_extent_buffer(path->nodes[0], eb, dest_offset, 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,26 +655,30 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
ret = btrfs_lookup_csums_range(root->log_root, ret = btrfs_lookup_csums_range(root->log_root,
csum_start, csum_end - 1, csum_start, csum_end - 1,
&ordered_sums, 0); &ordered_sums, 0);
BUG_ON(ret); if (ret)
goto out;
while (!list_empty(&ordered_sums)) { while (!list_empty(&ordered_sums)) {
struct btrfs_ordered_sum *sums; struct btrfs_ordered_sum *sums;
sums = list_entry(ordered_sums.next, sums = list_entry(ordered_sums.next,
struct btrfs_ordered_sum, struct btrfs_ordered_sum,
list); list);
ret = btrfs_csum_file_blocks(trans, if (!ret)
ret = btrfs_csum_file_blocks(trans,
root->fs_info->csum_root, root->fs_info->csum_root,
sums); sums);
BUG_ON(ret);
list_del(&sums->list); list_del(&sums->list);
kfree(sums); kfree(sums);
} }
if (ret)
goto out;
} else { } else {
btrfs_release_path(path); btrfs_release_path(path);
} }
} else if (found_type == BTRFS_FILE_EXTENT_INLINE) { } else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
/* inline extents are easy, we just overwrite them */ /* inline extents are easy, we just overwrite them */
ret = overwrite_item(trans, root, path, eb, slot, key); ret = overwrite_item(trans, root, path, eb, slot, key);
BUG_ON(ret); if (ret)
goto out;
} }
inode_add_bytes(inode, nbytes); inode_add_bytes(inode, nbytes);
...@@ -717,20 +723,21 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, ...@@ -717,20 +723,21 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans,
inode = read_one_inode(root, location.objectid); inode = read_one_inode(root, location.objectid);
if (!inode) { if (!inode) {
kfree(name); ret = -EIO;
return -EIO; goto out;
} }
ret = link_to_fixup_dir(trans, root, path, location.objectid); ret = link_to_fixup_dir(trans, root, path, location.objectid);
BUG_ON(ret); if (ret)
goto out;
ret = btrfs_unlink_inode(trans, root, dir, inode, name, name_len); ret = btrfs_unlink_inode(trans, root, dir, inode, name, name_len);
BUG_ON(ret); if (ret)
goto out;
btrfs_run_delayed_items(trans, root);
out:
kfree(name); kfree(name);
iput(inode); iput(inode);
btrfs_run_delayed_items(trans, root);
return ret; return ret;
} }
...@@ -883,7 +890,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, ...@@ -883,7 +890,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
victim_name_len = btrfs_inode_ref_name_len(leaf, victim_name_len = btrfs_inode_ref_name_len(leaf,
victim_ref); victim_ref);
victim_name = kmalloc(victim_name_len, GFP_NOFS); victim_name = kmalloc(victim_name_len, GFP_NOFS);
BUG_ON(!victim_name); if (!victim_name)
return -ENOMEM;
read_extent_buffer(leaf, victim_name, read_extent_buffer(leaf, victim_name,
(unsigned long)(victim_ref + 1), (unsigned long)(victim_ref + 1),
...@@ -899,9 +907,10 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, ...@@ -899,9 +907,10 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
ret = btrfs_unlink_inode(trans, root, dir, ret = btrfs_unlink_inode(trans, root, dir,
inode, victim_name, inode, victim_name,
victim_name_len); victim_name_len);
BUG_ON(ret);
btrfs_run_delayed_items(trans, root);
kfree(victim_name); kfree(victim_name);
if (ret)
return ret;
btrfs_run_delayed_items(trans, root);
*search_done = 1; *search_done = 1;
goto again; goto again;
} }
...@@ -909,7 +918,6 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, ...@@ -909,7 +918,6 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
ptr = (unsigned long)(victim_ref + 1) + victim_name_len; ptr = (unsigned long)(victim_ref + 1) + victim_name_len;
} }
BUG_ON(ret);
/* /*
* NOTE: we have searched root tree and checked the * NOTE: we have searched root tree and checked the
...@@ -943,6 +951,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, ...@@ -943,6 +951,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
goto next; goto next;
victim_name = kmalloc(victim_name_len, GFP_NOFS); victim_name = kmalloc(victim_name_len, GFP_NOFS);
if (!victim_name)
return -ENOMEM;
read_extent_buffer(leaf, victim_name, (unsigned long)&extref->name, read_extent_buffer(leaf, victim_name, (unsigned long)&extref->name,
victim_name_len); victim_name_len);
...@@ -969,14 +979,16 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, ...@@ -969,14 +979,16 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
victim_name_len); victim_name_len);
btrfs_run_delayed_items(trans, root); btrfs_run_delayed_items(trans, root);
} }
BUG_ON(ret);
iput(victim_parent); iput(victim_parent);
kfree(victim_name); kfree(victim_name);
if (ret)
return ret;
*search_done = 1; *search_done = 1;
goto again; goto again;
} }
kfree(victim_name); kfree(victim_name);
BUG_ON(ret); if (ret)
return ret;
next: next:
cur_offset += victim_name_len + sizeof(*extref); cur_offset += victim_name_len + sizeof(*extref);
} }
...@@ -989,7 +1001,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, ...@@ -989,7 +1001,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
ref_index, name, namelen, 0); ref_index, name, namelen, 0);
if (di && !IS_ERR(di)) { if (di && !IS_ERR(di)) {
ret = drop_one_dir_item(trans, root, path, dir, di); ret = drop_one_dir_item(trans, root, path, dir, di);
BUG_ON(ret); if (ret)
return ret;
} }
btrfs_release_path(path); btrfs_release_path(path);
...@@ -998,7 +1011,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, ...@@ -998,7 +1011,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
name, namelen, 0); name, namelen, 0);
if (di && !IS_ERR(di)) { if (di && !IS_ERR(di)) {
ret = drop_one_dir_item(trans, root, path, dir, di); ret = drop_one_dir_item(trans, root, path, dir, di);
BUG_ON(ret); if (ret)
return ret;
} }
btrfs_release_path(path); btrfs_release_path(path);
...@@ -1143,15 +1157,19 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, ...@@ -1143,15 +1157,19 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
parent_objectid, parent_objectid,
ref_index, name, namelen, ref_index, name, namelen,
&search_done); &search_done);
if (ret == 1) if (ret == 1) {
ret = 0;
goto out;
}
if (ret)
goto out; goto out;
BUG_ON(ret);
} }
/* insert our name */ /* insert our name */
ret = btrfs_add_link(trans, dir, inode, name, namelen, ret = btrfs_add_link(trans, dir, inode, name, namelen,
0, ref_index); 0, ref_index);
BUG_ON(ret); if (ret)
goto out;
btrfs_update_inode(trans, root, inode); btrfs_update_inode(trans, root, inode);
} }
...@@ -1166,13 +1184,11 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, ...@@ -1166,13 +1184,11 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
/* finally write the back reference in the inode */ /* finally write the back reference in the inode */
ret = overwrite_item(trans, root, path, eb, slot, key); ret = overwrite_item(trans, root, path, eb, slot, key);
BUG_ON(ret);
out: out:
btrfs_release_path(path); btrfs_release_path(path);
iput(dir); iput(dir);
iput(inode); iput(inode);
return 0; return ret;
} }
static int insert_orphan_item(struct btrfs_trans_handle *trans, static 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,10 +1346,10 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
if (S_ISDIR(inode->i_mode)) { if (S_ISDIR(inode->i_mode)) {
ret = replay_dir_deletes(trans, root, NULL, path, ret = replay_dir_deletes(trans, root, NULL, path,
ino, 1); ino, 1);
BUG_ON(ret); if (ret)
goto out;
} }
ret = insert_orphan_item(trans, root, ino); ret = insert_orphan_item(trans, root, ino);
BUG_ON(ret);
} }
out: out:
...@@ -1378,9 +1394,9 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, ...@@ -1378,9 +1394,9 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans,
return -EIO; return -EIO;
ret = fixup_inode_link_count(trans, root, inode); ret = fixup_inode_link_count(trans, root, inode);
BUG_ON(ret);
iput(inode); iput(inode);
if (ret)
goto out;
/* /*
* fixup on a directory may create new entries, * 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,7 +1446,7 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans,
} else if (ret == -EEXIST) { } else if (ret == -EEXIST) {
ret = 0; ret = 0;
} else { } else {
BUG(); BUG(); /* Logic Error */
} }
iput(inode); iput(inode);
...@@ -1499,7 +1515,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, ...@@ -1499,7 +1515,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
struct inode *dir; struct inode *dir;
u8 log_type; u8 log_type;
int exists; int exists;
int ret; int ret = 0;
dir = read_one_inode(root, key->objectid); dir = read_one_inode(root, key->objectid);
if (!dir) if (!dir)
...@@ -1531,7 +1547,9 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, ...@@ -1531,7 +1547,9 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
key->offset, name, key->offset, name,
name_len, 1); name_len, 1);
} else { } else {
BUG(); /* Corruption */
ret = -EINVAL;
goto out;
} }
if (IS_ERR_OR_NULL(dst_di)) { if (IS_ERR_OR_NULL(dst_di)) {
/* we need a sequence number to insert, so we only /* 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,7 +1577,8 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
goto out; goto out;
ret = drop_one_dir_item(trans, root, path, dir, dst_di); ret = drop_one_dir_item(trans, root, path, dir, dst_di);
BUG_ON(ret); if (ret)
goto out;
if (key->type == BTRFS_DIR_INDEX_KEY) if (key->type == BTRFS_DIR_INDEX_KEY)
goto insert; goto insert;
...@@ -1567,14 +1586,15 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, ...@@ -1567,14 +1586,15 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
btrfs_release_path(path); btrfs_release_path(path);
kfree(name); kfree(name);
iput(dir); iput(dir);
return 0; return ret;
insert: insert:
btrfs_release_path(path); btrfs_release_path(path);
ret = insert_one_name(trans, root, path, key->objectid, key->offset, ret = insert_one_name(trans, root, path, key->objectid, key->offset,
name, name_len, log_type, &log_key); name, name_len, log_type, &log_key);
if (ret && ret != -ENOENT)
BUG_ON(ret && ret != -ENOENT); goto out;
ret = 0;
goto out; goto out;
} }
...@@ -1605,7 +1625,8 @@ static noinline int replay_one_dir_item(struct btrfs_trans_handle *trans, ...@@ -1605,7 +1625,8 @@ static noinline int replay_one_dir_item(struct btrfs_trans_handle *trans,
return -EIO; return -EIO;
name_len = btrfs_dir_name_len(eb, di); name_len = btrfs_dir_name_len(eb, di);
ret = replay_one_name(trans, root, path, eb, di, key); ret = replay_one_name(trans, root, path, eb, di, key);
BUG_ON(ret); if (ret)
return ret;
ptr = (unsigned long)(di + 1); ptr = (unsigned long)(di + 1);
ptr += name_len; ptr += name_len;
} }
...@@ -1766,16 +1787,21 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans, ...@@ -1766,16 +1787,21 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans,
ret = link_to_fixup_dir(trans, root, ret = link_to_fixup_dir(trans, root,
path, location.objectid); path, location.objectid);
BUG_ON(ret); if (ret) {
kfree(name);
iput(inode);
goto out;
}
btrfs_inc_nlink(inode); btrfs_inc_nlink(inode);
ret = btrfs_unlink_inode(trans, root, dir, inode, ret = btrfs_unlink_inode(trans, root, dir, inode,
name, name_len); name, name_len);
BUG_ON(ret); if (!ret)
btrfs_run_delayed_items(trans, root);
btrfs_run_delayed_items(trans, root);
kfree(name); kfree(name);
iput(inode); iput(inode);
if (ret)
goto out;
/* there might still be more names under this key /* there might still be more names under this key
* check and repeat if required * check and repeat if required
...@@ -1879,7 +1905,8 @@ static noinline int replay_dir_deletes(struct btrfs_trans_handle *trans, ...@@ -1879,7 +1905,8 @@ static noinline int replay_dir_deletes(struct btrfs_trans_handle *trans,
ret = check_item_in_log(trans, root, log, path, ret = check_item_in_log(trans, root, log, path,
log_path, dir, log_path, dir,
&found_key); &found_key);
BUG_ON(ret); if (ret)
goto out;
if (found_key.offset == (u64)-1) if (found_key.offset == (u64)-1)
break; break;
dir_key.offset = found_key.offset + 1; dir_key.offset = found_key.offset + 1;
...@@ -2083,7 +2110,10 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, ...@@ -2083,7 +2110,10 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
BTRFS_TREE_LOG_OBJECTID); BTRFS_TREE_LOG_OBJECTID);
ret = btrfs_free_and_pin_reserved_extent(root, ret = btrfs_free_and_pin_reserved_extent(root,
bytenr, blocksize); bytenr, blocksize);
BUG_ON(ret); /* -ENOMEM or logic errors */ if (ret) {
free_extent_buffer(next);
return ret;
}
} }
free_extent_buffer(next); free_extent_buffer(next);
continue; continue;
...@@ -2156,7 +2186,8 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans, ...@@ -2156,7 +2186,8 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
ret = btrfs_free_and_pin_reserved_extent(root, ret = btrfs_free_and_pin_reserved_extent(root,
path->nodes[*level]->start, path->nodes[*level]->start,
path->nodes[*level]->len); path->nodes[*level]->len);
BUG_ON(ret); if (ret)
return ret;
} }
free_extent_buffer(path->nodes[*level]); free_extent_buffer(path->nodes[*level]);
path->nodes[*level] = NULL; path->nodes[*level] = NULL;
...@@ -2229,7 +2260,8 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, ...@@ -2229,7 +2260,8 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
BTRFS_TREE_LOG_OBJECTID); BTRFS_TREE_LOG_OBJECTID);
ret = btrfs_free_and_pin_reserved_extent(log, next->start, ret = btrfs_free_and_pin_reserved_extent(log, next->start,
next->len); next->len);
BUG_ON(ret); /* -ENOMEM or logic errors */ if (ret)
goto out;
} }
} }
...@@ -2517,7 +2549,10 @@ static void free_log_tree(struct btrfs_trans_handle *trans, ...@@ -2517,7 +2549,10 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
if (trans) { if (trans) {
ret = walk_log_tree(trans, log, &wc); ret = walk_log_tree(trans, log, &wc);
BUG_ON(ret);
/* I don't think this can happen but just in case */
if (ret)
btrfs_abort_transaction(trans, log, ret);
} }
while (1) { while (1) {
...@@ -2625,7 +2660,10 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, ...@@ -2625,7 +2660,10 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
if (di) { if (di) {
ret = btrfs_delete_one_dir_name(trans, log, path, di); ret = btrfs_delete_one_dir_name(trans, log, path, di);
bytes_del += name_len; bytes_del += name_len;
BUG_ON(ret); if (ret) {
err = ret;
goto fail;
}
} }
btrfs_release_path(path); btrfs_release_path(path);
di = btrfs_lookup_dir_index_item(trans, log, path, dir_ino, 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,7 +2675,10 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
if (di) { if (di) {
ret = btrfs_delete_one_dir_name(trans, log, path, di); ret = btrfs_delete_one_dir_name(trans, log, path, di);
bytes_del += name_len; bytes_del += name_len;
BUG_ON(ret); if (ret) {
err = ret;
goto fail;
}
} }
/* update the directory size in the log to reflect the names /* 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,7 +3017,7 @@ static int drop_objectid_items(struct btrfs_trans_handle *trans,
while (1) { while (1) {
ret = btrfs_search_slot(trans, log, &key, path, -1, 1); ret = btrfs_search_slot(trans, log, &key, path, -1, 1);
BUG_ON(ret == 0); BUG_ON(ret == 0); /* Logic error */
if (ret < 0) if (ret < 0)
break; break;
...@@ -3179,7 +3220,11 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, ...@@ -3179,7 +3220,11 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
log->fs_info->csum_root, log->fs_info->csum_root,
ds + cs, ds + cs + cl - 1, ds + cs, ds + cs + cl - 1,
&ordered_sums, 0); &ordered_sums, 0);
BUG_ON(ret); if (ret) {
btrfs_release_path(dst_path);
kfree(ins_data);
return ret;
}
} }
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册