Miklos Szeredi <miklos@xxxxxxxxxx> wrote: > I think the problem is that directory offsets are not consistent > between readdir and readdirplus. The solution is that userspace > should always use the same offsets. This makes the readdirplus > implementation more complex but that's really the only sane thing to > do. I think something like the following is necessary in the kernel, too. (Userspace patch coming) ------------------------------- 8< -------------------------------- >From ed52619fda61c8f2b723ef72666e7acdd8885a1c Mon Sep 17 00:00:00 2001 From: Eric Wong <normalperson@xxxxxxxx> Date: Tue, 5 Feb 2013 02:54:28 +0000 Subject: [PATCH] fuse: consistently use readdirplus offsets With adaptive readdirplus, filesystems may switch between normal readdir or readdirplus requests. However, directory offsets must be maintained consistently to prevent the kernel from misinterpreting the offsets between different requests which may use the same buffer. Signed-off-by: Eric Wong <normalperson@xxxxxxxx> --- fs/fuse/dir.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index dc5e648..a8e4abb 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1313,7 +1313,7 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) { - int plus, err; + int err; size_t nbytes; struct page *page; struct inode *inode = file->f_path.dentry->d_inode; @@ -1334,12 +1334,11 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) return -ENOMEM; } - plus = fuse_use_readdirplus(inode, file); req->out.argpages = 1; req->num_pages = 1; req->pages[0] = page; req->page_descs[0].length = PAGE_SIZE; - if (plus) { + if (fuse_use_readdirplus(inode, file)) { attr_version = fuse_get_attr_version(fc); fuse_read_fill(req, file, file->f_pos, PAGE_SIZE, FUSE_READDIRPLUS); @@ -1352,7 +1351,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) err = req->out.h.error; fuse_put_request(fc, req); if (!err) { - if (plus) { + if (fc->do_readdirplus) { err = parse_dirplusfile(page_address(page), nbytes, file, dstbuf, filldir, attr_version); -- Eric Wong -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html