[PATCH] kill-the-bkl/reiserfs: fix early readdir offset increment

From: Frederic Weisbecker
Date: Sun Aug 09 2009 - 18:53:45 EST


The previous commit:
"kill-the-bkl/reiserfs: release the lock only for first entry in readdir"
brought a bug which increments the readdir offset even if we failed to
copy a directory entry through filldir.

Then if we are in the end of the user buffer, there are chances that
getdents() will be subsequently called with a new buffer to continue
fetching the directory. At this time the directory entry offset will
be wrong because it has omitted the previous entry that failed to copy.

We need to increment the directory offset after fetching an entry, not
before.

This fixes weird bugs in which a directory seems not empty whereas
it is.

Signed-off-by: Frederic Weisbecker <fweisbec@xxxxxxxxx>
Cc: Jeff Mahoney <jeffm@xxxxxxxx>
Cc: Chris Mason <chris.mason@xxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxx>
Cc: Alexander Beregalov <a.beregalov@xxxxxxxxx>
---
fs/reiserfs/dir.c | 21 +++++++++++----------
1 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index d6fb8d3..d4477eb 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -195,12 +195,6 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent,
*pos = d_off;
d_ino = deh_objectid(deh);

- /*
- * next entry should be looked for with such
- * offset
- */
- next_pos = deh_offset(deh) + 1;
-
if (first_entry) {
int fillret;

@@ -221,11 +215,18 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent,

if (item_moved(&tmp_ih, &path_to_entry))
goto research;
- continue;
- }
- if (filldir(dirent, d_name, d_reclen, d_off,
- d_ino, DT_UNKNOWN) < 0)
+ } else {
+ if (filldir(dirent, d_name, d_reclen,
+ d_off, d_ino, DT_UNKNOWN) < 0)
goto end;
+ }
+
+ /*
+ * next entry should be looked for with such
+ * offset
+ */
+ next_pos = deh_offset(deh) + 1;
+
} /* for */
}

--
1.6.2.3


You can find this patch and the other in this series in the following git
tree:

git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing.git
reiserfs/kill-bkl

Thanks.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/