提交 d3316c82 编写于 作者: N Nikolay Borisov 提交者: David Sterba

btrfs: Properly handle backref_in_log retval

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: NNikolay Borisov <nborisov@suse.com>
Reviewed-by: NDavid Sterba <dsterba@suse.com>
Signed-off-by: NDavid Sterba <dsterba@suse.com>
上级 89cbf5f6
...@@ -952,7 +952,9 @@ static noinline int backref_in_log(struct btrfs_root *log, ...@@ -952,7 +952,9 @@ static noinline int backref_in_log(struct btrfs_root *log,
return -ENOMEM; return -ENOMEM;
ret = btrfs_search_slot(NULL, log, key, path, 0, 0); ret = btrfs_search_slot(NULL, log, key, path, 0, 0);
if (ret != 0) { if (ret < 0) {
goto out;
} else if (ret == 1) {
ret = 0; ret = 0;
goto out; goto out;
} }
...@@ -1026,10 +1028,13 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, ...@@ -1026,10 +1028,13 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
(unsigned long)(victim_ref + 1), (unsigned long)(victim_ref + 1),
victim_name_len); victim_name_len);
if (!backref_in_log(log_root, &search_key, ret = backref_in_log(log_root, &search_key,
parent_objectid, parent_objectid, victim_name,
victim_name, victim_name_len);
victim_name_len)) { if (ret < 0) {
kfree(victim_name);
return ret;
} else if (!ret) {
inc_nlink(&inode->vfs_inode); inc_nlink(&inode->vfs_inode);
btrfs_release_path(path); btrfs_release_path(path);
...@@ -1091,10 +1096,12 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, ...@@ -1091,10 +1096,12 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
search_key.offset = btrfs_extref_hash(parent_objectid, search_key.offset = btrfs_extref_hash(parent_objectid,
victim_name, victim_name,
victim_name_len); victim_name_len);
ret = 0; ret = backref_in_log(log_root, &search_key,
if (!backref_in_log(log_root, &search_key, parent_objectid, victim_name,
parent_objectid, victim_name, victim_name_len);
victim_name_len)) { if (ret < 0) {
return ret;
} else if (!ret) {
ret = -ENOENT; ret = -ENOENT;
victim_parent = read_one_inode(root, victim_parent = read_one_inode(root,
parent_objectid); parent_objectid);
...@@ -1869,16 +1876,19 @@ static bool name_in_log_ref(struct btrfs_root *log_root, ...@@ -1869,16 +1876,19 @@ static bool name_in_log_ref(struct btrfs_root *log_root,
const u64 dirid, const u64 ino) const u64 dirid, const u64 ino)
{ {
struct btrfs_key search_key; struct btrfs_key search_key;
int ret;
search_key.objectid = ino; search_key.objectid = ino;
search_key.type = BTRFS_INODE_REF_KEY; search_key.type = BTRFS_INODE_REF_KEY;
search_key.offset = dirid; 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; return true;
search_key.type = BTRFS_INODE_EXTREF_KEY; search_key.type = BTRFS_INODE_EXTREF_KEY;
search_key.offset = btrfs_extref_hash(dirid, name, name_len); 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 true;
return false; return false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册