|
@@ -589,7 +589,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
|
|
|
|
|
|
/* drop any overlapping extents */
|
|
|
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 ||
|
|
|
found_type == BTRFS_FILE_EXTENT_PREALLOC) {
|
|
@@ -599,7 +600,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
|
|
|
|
|
|
ret = btrfs_insert_empty_item(trans, root, path, key,
|
|
|
sizeof(*item));
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
dest_offset = btrfs_item_ptr_offset(path->nodes[0],
|
|
|
path->slots[0]);
|
|
|
copy_extent_buffer(path->nodes[0], eb, dest_offset,
|
|
@@ -653,26 +655,30 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
|
|
|
ret = btrfs_lookup_csums_range(root->log_root,
|
|
|
csum_start, csum_end - 1,
|
|
|
&ordered_sums, 0);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
while (!list_empty(&ordered_sums)) {
|
|
|
struct btrfs_ordered_sum *sums;
|
|
|
sums = list_entry(ordered_sums.next,
|
|
|
struct btrfs_ordered_sum,
|
|
|
list);
|
|
|
- ret = btrfs_csum_file_blocks(trans,
|
|
|
+ if (!ret)
|
|
|
+ ret = btrfs_csum_file_blocks(trans,
|
|
|
root->fs_info->csum_root,
|
|
|
sums);
|
|
|
- BUG_ON(ret);
|
|
|
list_del(&sums->list);
|
|
|
kfree(sums);
|
|
|
}
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
} else {
|
|
|
btrfs_release_path(path);
|
|
|
}
|
|
|
} else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
|
|
|
/* inline extents are easy, we just overwrite them */
|
|
|
ret = overwrite_item(trans, root, path, eb, slot, key);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
inode_add_bytes(inode, nbytes);
|
|
@@ -717,20 +723,21 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans,
|
|
|
|
|
|
inode = read_one_inode(root, location.objectid);
|
|
|
if (!inode) {
|
|
|
- kfree(name);
|
|
|
- return -EIO;
|
|
|
+ ret = -EIO;
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
+ btrfs_run_delayed_items(trans, root);
|
|
|
+out:
|
|
|
kfree(name);
|
|
|
-
|
|
|
iput(inode);
|
|
|
-
|
|
|
- btrfs_run_delayed_items(trans, root);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -883,7 +890,8 @@ again:
|
|
|
victim_name_len = btrfs_inode_ref_name_len(leaf,
|
|
|
victim_ref);
|
|
|
victim_name = kmalloc(victim_name_len, GFP_NOFS);
|
|
|
- BUG_ON(!victim_name);
|
|
|
+ if (!victim_name)
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
read_extent_buffer(leaf, victim_name,
|
|
|
(unsigned long)(victim_ref + 1),
|
|
@@ -899,9 +907,10 @@ again:
|
|
|
ret = btrfs_unlink_inode(trans, root, dir,
|
|
|
inode, victim_name,
|
|
|
victim_name_len);
|
|
|
- BUG_ON(ret);
|
|
|
- btrfs_run_delayed_items(trans, root);
|
|
|
kfree(victim_name);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ btrfs_run_delayed_items(trans, root);
|
|
|
*search_done = 1;
|
|
|
goto again;
|
|
|
}
|
|
@@ -909,7 +918,6 @@ again:
|
|
|
|
|
|
ptr = (unsigned long)(victim_ref + 1) + victim_name_len;
|
|
|
}
|
|
|
- BUG_ON(ret);
|
|
|
|
|
|
/*
|
|
|
* NOTE: we have searched root tree and checked the
|
|
@@ -943,6 +951,8 @@ again:
|
|
|
goto next;
|
|
|
|
|
|
victim_name = kmalloc(victim_name_len, GFP_NOFS);
|
|
|
+ if (!victim_name)
|
|
|
+ return -ENOMEM;
|
|
|
read_extent_buffer(leaf, victim_name, (unsigned long)&extref->name,
|
|
|
victim_name_len);
|
|
|
|
|
@@ -969,14 +979,16 @@ again:
|
|
|
victim_name_len);
|
|
|
btrfs_run_delayed_items(trans, root);
|
|
|
}
|
|
|
- BUG_ON(ret);
|
|
|
iput(victim_parent);
|
|
|
kfree(victim_name);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
*search_done = 1;
|
|
|
goto again;
|
|
|
}
|
|
|
kfree(victim_name);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
next:
|
|
|
cur_offset += victim_name_len + sizeof(*extref);
|
|
|
}
|
|
@@ -989,7 +1001,8 @@ next:
|
|
|
ref_index, name, namelen, 0);
|
|
|
if (di && !IS_ERR(di)) {
|
|
|
ret = drop_one_dir_item(trans, root, path, dir, di);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
}
|
|
|
btrfs_release_path(path);
|
|
|
|
|
@@ -998,7 +1011,8 @@ next:
|
|
|
name, namelen, 0);
|
|
|
if (di && !IS_ERR(di)) {
|
|
|
ret = drop_one_dir_item(trans, root, path, dir, di);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
}
|
|
|
btrfs_release_path(path);
|
|
|
|
|
@@ -1143,15 +1157,19 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
|
|
|
parent_objectid,
|
|
|
ref_index, name, namelen,
|
|
|
&search_done);
|
|
|
- if (ret == 1)
|
|
|
+ if (ret == 1) {
|
|
|
+ ret = 0;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ if (ret)
|
|
|
goto out;
|
|
|
- BUG_ON(ret);
|
|
|
}
|
|
|
|
|
|
/* insert our name */
|
|
|
ret = btrfs_add_link(trans, dir, inode, name, namelen,
|
|
|
0, ref_index);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
|
|
|
btrfs_update_inode(trans, root, inode);
|
|
|
}
|
|
@@ -1166,13 +1184,11 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
|
|
|
|
|
|
/* finally write the back reference in the inode */
|
|
|
ret = overwrite_item(trans, root, path, eb, slot, key);
|
|
|
- BUG_ON(ret);
|
|
|
-
|
|
|
out:
|
|
|
btrfs_release_path(path);
|
|
|
iput(dir);
|
|
|
iput(inode);
|
|
|
- return 0;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
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,
|
|
|
if (S_ISDIR(inode->i_mode)) {
|
|
|
ret = replay_dir_deletes(trans, root, NULL, path,
|
|
|
ino, 1);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
}
|
|
|
ret = insert_orphan_item(trans, root, ino);
|
|
|
- BUG_ON(ret);
|
|
|
}
|
|
|
|
|
|
out:
|
|
@@ -1378,9 +1394,9 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans,
|
|
|
return -EIO;
|
|
|
|
|
|
ret = fixup_inode_link_count(trans, root, inode);
|
|
|
- BUG_ON(ret);
|
|
|
-
|
|
|
iput(inode);
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
|
|
|
/*
|
|
|
* fixup on a directory may create new entries,
|
|
@@ -1430,7 +1446,7 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans,
|
|
|
} else if (ret == -EEXIST) {
|
|
|
ret = 0;
|
|
|
} else {
|
|
|
- BUG();
|
|
|
+ BUG(); /* Logic Error */
|
|
|
}
|
|
|
iput(inode);
|
|
|
|
|
@@ -1499,7 +1515,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
|
|
|
struct inode *dir;
|
|
|
u8 log_type;
|
|
|
int exists;
|
|
|
- int ret;
|
|
|
+ int ret = 0;
|
|
|
|
|
|
dir = read_one_inode(root, key->objectid);
|
|
|
if (!dir)
|
|
@@ -1531,7 +1547,9 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
|
|
|
key->offset, name,
|
|
|
name_len, 1);
|
|
|
} else {
|
|
|
- BUG();
|
|
|
+ /* Corruption */
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto out;
|
|
|
}
|
|
|
if (IS_ERR_OR_NULL(dst_di)) {
|
|
|
/* 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,
|
|
|
goto out;
|
|
|
|
|
|
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)
|
|
|
goto insert;
|
|
@@ -1567,14 +1586,15 @@ out:
|
|
|
btrfs_release_path(path);
|
|
|
kfree(name);
|
|
|
iput(dir);
|
|
|
- return 0;
|
|
|
+ return ret;
|
|
|
|
|
|
insert:
|
|
|
btrfs_release_path(path);
|
|
|
ret = insert_one_name(trans, root, path, key->objectid, key->offset,
|
|
|
name, name_len, log_type, &log_key);
|
|
|
-
|
|
|
- BUG_ON(ret && ret != -ENOENT);
|
|
|
+ if (ret && ret != -ENOENT)
|
|
|
+ goto out;
|
|
|
+ ret = 0;
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
@@ -1605,7 +1625,8 @@ static noinline int replay_one_dir_item(struct btrfs_trans_handle *trans,
|
|
|
return -EIO;
|
|
|
name_len = btrfs_dir_name_len(eb, di);
|
|
|
ret = replay_one_name(trans, root, path, eb, di, key);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
ptr = (unsigned long)(di + 1);
|
|
|
ptr += name_len;
|
|
|
}
|
|
@@ -1766,16 +1787,21 @@ again:
|
|
|
|
|
|
ret = link_to_fixup_dir(trans, root,
|
|
|
path, location.objectid);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret) {
|
|
|
+ kfree(name);
|
|
|
+ iput(inode);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
btrfs_inc_nlink(inode);
|
|
|
ret = btrfs_unlink_inode(trans, root, dir, inode,
|
|
|
name, name_len);
|
|
|
- BUG_ON(ret);
|
|
|
-
|
|
|
- btrfs_run_delayed_items(trans, root);
|
|
|
-
|
|
|
+ if (!ret)
|
|
|
+ btrfs_run_delayed_items(trans, root);
|
|
|
kfree(name);
|
|
|
iput(inode);
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
|
|
|
/* there might still be more names under this key
|
|
|
* check and repeat if required
|
|
@@ -1879,7 +1905,8 @@ again:
|
|
|
ret = check_item_in_log(trans, root, log, path,
|
|
|
log_path, dir,
|
|
|
&found_key);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
if (found_key.offset == (u64)-1)
|
|
|
break;
|
|
|
dir_key.offset = found_key.offset + 1;
|
|
@@ -2083,7 +2110,10 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
|
|
|
BTRFS_TREE_LOG_OBJECTID);
|
|
|
ret = btrfs_free_and_pin_reserved_extent(root,
|
|
|
bytenr, blocksize);
|
|
|
- BUG_ON(ret); /* -ENOMEM or logic errors */
|
|
|
+ if (ret) {
|
|
|
+ free_extent_buffer(next);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
}
|
|
|
free_extent_buffer(next);
|
|
|
continue;
|
|
@@ -2156,7 +2186,8 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
|
|
|
ret = btrfs_free_and_pin_reserved_extent(root,
|
|
|
path->nodes[*level]->start,
|
|
|
path->nodes[*level]->len);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
}
|
|
|
free_extent_buffer(path->nodes[*level]);
|
|
|
path->nodes[*level] = NULL;
|
|
@@ -2229,7 +2260,8 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
|
|
|
BTRFS_TREE_LOG_OBJECTID);
|
|
|
ret = btrfs_free_and_pin_reserved_extent(log, next->start,
|
|
|
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,
|
|
|
|
|
|
if (trans) {
|
|
|
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) {
|
|
@@ -2625,7 +2660,10 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
|
|
|
if (di) {
|
|
|
ret = btrfs_delete_one_dir_name(trans, log, path, di);
|
|
|
bytes_del += name_len;
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret) {
|
|
|
+ err = ret;
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
}
|
|
|
btrfs_release_path(path);
|
|
|
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,
|
|
|
if (di) {
|
|
|
ret = btrfs_delete_one_dir_name(trans, log, path, di);
|
|
|
bytes_del += name_len;
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret) {
|
|
|
+ err = ret;
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* 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,
|
|
|
|
|
|
while (1) {
|
|
|
ret = btrfs_search_slot(trans, log, &key, path, -1, 1);
|
|
|
- BUG_ON(ret == 0);
|
|
|
+ BUG_ON(ret == 0); /* Logic error */
|
|
|
if (ret < 0)
|
|
|
break;
|
|
|
|
|
@@ -3179,7 +3220,11 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
|
|
|
log->fs_info->csum_root,
|
|
|
ds + cs, ds + cs + cl - 1,
|
|
|
&ordered_sums, 0);
|
|
|
- BUG_ON(ret);
|
|
|
+ if (ret) {
|
|
|
+ btrfs_release_path(dst_path);
|
|
|
+ kfree(ins_data);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|