btrfs-progs: improve error handling in btrfs_split_item()
This involves the following error cases: - Unable to find the original item Return -EAGAIN and release the path (which is not done in the original code) - Error from split_leaf() Remove the BUG_ON() and handle the error. The most common error is ENOSPC. - Error from kmalloc() Just handle the error and return -ENOMEM. Issue: #312 Signed-off-by: Qu Wenruo <wqu@suse.com>
This commit is contained in:
parent
66f08f9528
commit
2d164b3ee5
|
@ -2450,7 +2450,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
|
||||||
u32 nritems;
|
u32 nritems;
|
||||||
u32 orig_offset;
|
u32 orig_offset;
|
||||||
struct btrfs_disk_key disk_key;
|
struct btrfs_disk_key disk_key;
|
||||||
char *buf;
|
char *buf = NULL;
|
||||||
|
|
||||||
leaf = path->nodes[0];
|
leaf = path->nodes[0];
|
||||||
btrfs_item_key_to_cpu(leaf, &orig_key, path->slots[0]);
|
btrfs_item_key_to_cpu(leaf, &orig_key, path->slots[0]);
|
||||||
|
@ -2469,11 +2469,13 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
|
||||||
/* if our item isn't there or got smaller, return now */
|
/* if our item isn't there or got smaller, return now */
|
||||||
if (ret != 0 || item_size != btrfs_item_size(path->nodes[0],
|
if (ret != 0 || item_size != btrfs_item_size(path->nodes[0],
|
||||||
path->slots[0])) {
|
path->slots[0])) {
|
||||||
return -EAGAIN;
|
ret = -EAGAIN;
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = split_leaf(trans, root, &orig_key, path, 0, 0);
|
ret = split_leaf(trans, root, &orig_key, path, 0, 0);
|
||||||
BUG_ON(ret);
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
BUG_ON(btrfs_leaf_free_space(leaf) < sizeof(struct btrfs_item));
|
BUG_ON(btrfs_leaf_free_space(leaf) < sizeof(struct btrfs_item));
|
||||||
leaf = path->nodes[0];
|
leaf = path->nodes[0];
|
||||||
|
@ -2484,7 +2486,10 @@ split:
|
||||||
|
|
||||||
|
|
||||||
buf = kmalloc(item_size, GFP_NOFS);
|
buf = kmalloc(item_size, GFP_NOFS);
|
||||||
BUG_ON(!buf);
|
if (!buf) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf,
|
read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf,
|
||||||
path->slots[0]), item_size);
|
path->slots[0]), item_size);
|
||||||
slot = path->slots[0] + 1;
|
slot = path->slots[0] + 1;
|
||||||
|
@ -2530,6 +2535,10 @@ split:
|
||||||
}
|
}
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
return ret;
|
return ret;
|
||||||
|
error:
|
||||||
|
kfree(buf);
|
||||||
|
btrfs_release_path(path);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end)
|
void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end)
|
||||||
|
|
Loading…
Reference in New Issue