Skip to content

Commit

Permalink
btrfs: Properly handle backref_in_log retval
Browse files Browse the repository at this point in the history
This function can return a negative error value if btrfs_search_slot
errors for whatever reason or if btrfs_alloc_path runs out of memory.
This is currently problemattic because backref_in_log is treated by its
callers as if it returns boolean.

Fix this by adding proper error handling in callers. That also enables
the function to return the direct error code from btrfs_search_slot.

Signed-off-by: Nikolay Borisov <[email protected]>
Reviewed-by: David Sterba <[email protected]>
Signed-off-by: David Sterba <[email protected]>
  • Loading branch information
lorddoskias authored and kdave committed Nov 18, 2019
1 parent 89cbf5f commit d3316c8
Showing 1 changed file with 21 additions and 11 deletions.
32 changes: 21 additions & 11 deletions fs/btrfs/tree-log.c
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,9 @@ static noinline int backref_in_log(struct btrfs_root *log,
return -ENOMEM;

ret = btrfs_search_slot(NULL, log, key, path, 0, 0);
if (ret != 0) {
if (ret < 0) {
goto out;
} else if (ret == 1) {
ret = 0;
goto out;
}
Expand Down Expand Up @@ -1026,10 +1028,13 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
(unsigned long)(victim_ref + 1),
victim_name_len);

if (!backref_in_log(log_root, &search_key,
parent_objectid,
victim_name,
victim_name_len)) {
ret = backref_in_log(log_root, &search_key,
parent_objectid, victim_name,
victim_name_len);
if (ret < 0) {
kfree(victim_name);
return ret;
} else if (!ret) {
inc_nlink(&inode->vfs_inode);
btrfs_release_path(path);

Expand Down Expand Up @@ -1091,10 +1096,12 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
search_key.offset = btrfs_extref_hash(parent_objectid,
victim_name,
victim_name_len);
ret = 0;
if (!backref_in_log(log_root, &search_key,
parent_objectid, victim_name,
victim_name_len)) {
ret = backref_in_log(log_root, &search_key,
parent_objectid, victim_name,
victim_name_len);
if (ret < 0) {
return ret;
} else if (!ret) {
ret = -ENOENT;
victim_parent = read_one_inode(root,
parent_objectid);
Expand Down Expand Up @@ -1869,16 +1876,19 @@ static bool name_in_log_ref(struct btrfs_root *log_root,
const u64 dirid, const u64 ino)
{
struct btrfs_key search_key;
int ret;

search_key.objectid = ino;
search_key.type = BTRFS_INODE_REF_KEY;
search_key.offset = dirid;
if (backref_in_log(log_root, &search_key, dirid, name, name_len))
ret = backref_in_log(log_root, &search_key, dirid, name, name_len);
if (ret == 1)
return true;

search_key.type = BTRFS_INODE_EXTREF_KEY;
search_key.offset = btrfs_extref_hash(dirid, name, name_len);
if (backref_in_log(log_root, &search_key, dirid, name, name_len))
ret = backref_in_log(log_root, &search_key, dirid, name, name_len);
if (ret == 1)
return true;

return false;
Expand Down

0 comments on commit d3316c8

Please sign in to comment.