From: Amir Goldstein <amir73il@gmail.com> Date: Thu, 2 Jan 2025 20:14:01 +0000 (+0100) Subject: Fix junk readdirplus results when filesystem not filling stat info X-Git-Tag: fuse-3.17.1-rc0~24 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=e18535657101f79ab742d81c567bb03f108acae0;p=qemu-gpiodev%2Flibfuse.git Fix junk readdirplus results when filesystem not filling stat info Commit dd95d13a ("fix readdirplus when filler is called with zero offset (#896)) broke readdirplus with passthrough example command: passthrough -o auto_cache,modules=subdir,subdir=/src /mnt The /src directory looks like this: ~# ls -l /src total 0 drwx------ 3 root root 60 Jan 2 17:51 testdir And the fuse directory looks like this: ~# ls -l /mnt total 0 d--------- 0 root root 0 Jan 1 1970 testdir Because readdir_fill_from_list() ignores the fact that filesystem did not pass the FUSE_FILL_DIR_PLUS flag with valid stat info. Signed-off-by: Amir Goldstein <amir73il@gmail.com> --- diff --git a/lib/fuse.c b/lib/fuse.c index a1537af..aa5c611 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -163,6 +163,7 @@ struct node_lru { struct fuse_direntry { struct stat stat; + enum fuse_fill_dir_flags flags; char *name; struct fuse_direntry *next; }; @@ -3437,7 +3438,7 @@ static int extend_contents(struct fuse_dh *dh, unsigned minsize) } static int fuse_add_direntry_to_dh(struct fuse_dh *dh, const char *name, - struct stat *st) + struct stat *st, enum fuse_fill_dir_flags flags) { struct fuse_direntry *de; @@ -3452,6 +3453,7 @@ static int fuse_add_direntry_to_dh(struct fuse_dh *dh, const char *name, free(de); return -1; } + de->flags = flags; de->stat = *st; de->next = NULL; @@ -3529,7 +3531,7 @@ static int fill_dir(void *dh_, const char *name, const struct stat *statp, } else { dh->filled = 1; - if (fuse_add_direntry_to_dh(dh, name, &stbuf) == -1) + if (fuse_add_direntry_to_dh(dh, name, &stbuf, flags) == -1) return 1; } return 0; @@ -3607,7 +3609,7 @@ static int fill_dir_plus(void *dh_, const char *name, const struct stat *statp, } else { dh->filled = 1; - if (fuse_add_direntry_to_dh(dh, name, &e.attr) == -1) + if (fuse_add_direntry_to_dh(dh, name, &e.attr, flags) == -1) return 1; } @@ -3695,7 +3697,8 @@ static int readdir_fill_from_list(fuse_req_t req, struct fuse_dh *dh, .attr = de->stat, }; - if (!is_dot_or_dotdot(de->name)) { + if (de->flags & FUSE_FILL_DIR_PLUS && + !is_dot_or_dotdot(de->name)) { res = do_lookup(dh->fuse, dh->nodeid, de->name, &e); if (res) {