Commit b9e03af0 authored by Li Zefan's avatar Li Zefan

Btrfs: Check if btrfs_next_leaf() returns error in btrfs_real_readdir()

btrfs_next_leaf() can return -errno, and we should propagate
it to userspace.

This also simplifies how we walk the btree path.
Signed-off-by: default avatarLi Zefan <lizf@cn.fujitsu.com>
parent 2e6a0035
...@@ -4221,10 +4221,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, ...@@ -4221,10 +4221,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
struct btrfs_key found_key; struct btrfs_key found_key;
struct btrfs_path *path; struct btrfs_path *path;
int ret; int ret;
u32 nritems;
struct extent_buffer *leaf; struct extent_buffer *leaf;
int slot; int slot;
int advance;
unsigned char d_type; unsigned char d_type;
int over = 0; int over = 0;
u32 di_cur; u32 di_cur;
...@@ -4267,27 +4265,19 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, ...@@ -4267,27 +4265,19 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
if (ret < 0) if (ret < 0)
goto err; goto err;
advance = 0;
while (1) { while (1) {
leaf = path->nodes[0]; leaf = path->nodes[0];
nritems = btrfs_header_nritems(leaf);
slot = path->slots[0]; slot = path->slots[0];
if (advance || slot >= nritems) { if (slot >= btrfs_header_nritems(leaf)) {
if (slot >= nritems - 1) {
ret = btrfs_next_leaf(root, path); ret = btrfs_next_leaf(root, path);
if (ret) if (ret < 0)
goto err;
else if (ret > 0)
break; break;
leaf = path->nodes[0]; continue;
nritems = btrfs_header_nritems(leaf);
slot = path->slots[0];
} else {
slot++;
path->slots[0]++;
}
} }
advance = 1;
item = btrfs_item_nr(leaf, slot); item = btrfs_item_nr(leaf, slot);
btrfs_item_key_to_cpu(leaf, &found_key, slot); btrfs_item_key_to_cpu(leaf, &found_key, slot);
...@@ -4296,7 +4286,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, ...@@ -4296,7 +4286,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
if (btrfs_key_type(&found_key) != key_type) if (btrfs_key_type(&found_key) != key_type)
break; break;
if (found_key.offset < filp->f_pos) if (found_key.offset < filp->f_pos)
continue; goto next;
filp->f_pos = found_key.offset; filp->f_pos = found_key.offset;
...@@ -4349,6 +4339,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, ...@@ -4349,6 +4339,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
di_cur += di_len; di_cur += di_len;
di = (struct btrfs_dir_item *)((char *)di + di_len); di = (struct btrfs_dir_item *)((char *)di + di_len);
} }
next:
path->slots[0]++;
} }
/* Reached end of directory/root. Bump pos past the last item. */ /* Reached end of directory/root. Bump pos past the last item. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment