summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLi Zefan <lizf@cn.fujitsu.com>2011-03-23 10:43:58 +0800
committerLi Zefan <lizf@cn.fujitsu.com>2011-04-13 14:25:31 +0800
commitb9e03af0bcc11310f6be4a3951c9ee2c26465011 (patch)
treef7a89518879e38ae460f6b3c2e6cc9a32c7243bc
parent2e6a00356a066d34cd00872b067589549169ad48 (diff)
downloadlinux-b9e03af0bcc11310f6be4a3951c9ee2c26465011.tar.gz
linux-b9e03af0bcc11310f6be4a3951c9ee2c26465011.tar.bz2
linux-b9e03af0bcc11310f6be4a3951c9ee2c26465011.zip
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: Li Zefan <lizf@cn.fujitsu.com>
-rw-r--r--fs/btrfs/inode.c28
1 files changed, 10 insertions, 18 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 55a6a0b416d7..b9f7f5258343 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4221,10 +4221,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
struct btrfs_key found_key;
struct btrfs_path *path;
int ret;
- u32 nritems;
struct extent_buffer *leaf;
int slot;
- int advance;
unsigned char d_type;
int over = 0;
u32 di_cur;
@@ -4267,27 +4265,19 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
if (ret < 0)
goto err;
- advance = 0;
while (1) {
leaf = path->nodes[0];
- nritems = btrfs_header_nritems(leaf);
slot = path->slots[0];
- if (advance || slot >= nritems) {
- if (slot >= nritems - 1) {
- ret = btrfs_next_leaf(root, path);
- if (ret)
- break;
- leaf = path->nodes[0];
- nritems = btrfs_header_nritems(leaf);
- slot = path->slots[0];
- } else {
- slot++;
- path->slots[0]++;
- }
+ if (slot >= btrfs_header_nritems(leaf)) {
+ ret = btrfs_next_leaf(root, path);
+ if (ret < 0)
+ goto err;
+ else if (ret > 0)
+ break;
+ continue;
}
- advance = 1;
item = btrfs_item_nr(leaf, slot);
btrfs_item_key_to_cpu(leaf, &found_key, slot);
@@ -4296,7 +4286,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
if (btrfs_key_type(&found_key) != key_type)
break;
if (found_key.offset < filp->f_pos)
- continue;
+ goto next;
filp->f_pos = found_key.offset;
@@ -4349,6 +4339,8 @@ skip:
di_cur += 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. */