Add missing patch:
[ext4-patch-queue.git] / dx_readdir_hash_collision_fix.patch
bloba95ab2a9d77b85358d760b5f6f2890ec519bbad0
1 ext4: Fix ext4_dx_readdir hash collision handling
3 This fixes a bug where readdir() would return a directory entry twice
4 if there was a hash collision in an hash tree indexed directory.
6 Signed-off-by: Eugene Dashevsky <eugene@ibrix.com>
7 Signed-off-by: Mike Snitzer <msnitzer@ibrix.com>
8 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
9 ---
10 diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
11 index 05346fb..2f95937 100644
12 --- a/fs/ext4/dir.c
13 +++ b/fs/ext4/dir.c
14 @@ -412,7 +412,7 @@ static int call_filldir(struct file * filp, void * dirent,
15 get_dtype(sb, fname->file_type));
16 if (error) {
17 filp->f_pos = curr_pos;
18 - info->extra_fname = fname->next;
19 + info->extra_fname = fname;
20 return error;
22 fname = fname->next;
23 @@ -451,11 +451,21 @@ static int ext4_dx_readdir(struct file * filp,
24 * If there are any leftover names on the hash collision
25 * chain, return them first.
27 - if (info->extra_fname &&
28 - call_filldir(filp, dirent, filldir, info->extra_fname))
29 - goto finished;
31 - if (!info->curr_node)
32 + if (info->extra_fname) {
33 + if (call_filldir(filp, dirent, filldir, info->extra_fname))
34 + goto finished;
36 + info->extra_fname = NULL;
37 + info->curr_node = rb_next(info->curr_node);
38 + if (!info->curr_node) {
39 + if (info->next_hash == ~0) {
40 + filp->f_pos = EXT4_HTREE_EOF;
41 + goto finished;
42 + }
43 + info->curr_hash = info->next_hash;
44 + info->curr_minor_hash = 0;
45 + }
46 + } else if (!info->curr_node)
47 info->curr_node = rb_first(&info->root);
49 while (1) {