diff options
author | Jean-Pierre André <jpandre@users.noreply.github.com> | 2021-03-18 10:52:30 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-18 09:52:30 +0000 |
commit | bdd2d4110fbc6d2059eb699efad2cca4a7eacccb (patch) | |
tree | 62ca0ce9b94529a68e376922963993606af2f35a | |
parent | 77d662459a0fcdf358d515477d33795837e859d5 (diff) | |
download | libfuse-bdd2d4110fbc6d2059eb699efad2cca4a7eacccb.tar.gz |
Fix returning d_ino and d_type by readdir(3) in non-plus mode
When not using the readdir_plus mode, the d_type was not returned,
and the use_ino flag was not used for returning d_ino.
This patch fixes the returned values for d_ino and d_type by readdir(3)
The test for the returned value of d_ino has been adjusted to also
take the d_type into consideration and to check the returned values in
both basic readdir and readdir_plus modes. This is done by executing
the passthrough test twice.
Co-authored-by: Jean-Pierre André <jpandre@users.sourceforge.net>
-rw-r--r-- | ChangeLog.rst | 2 | ||||
-rw-r--r-- | example/passthrough.c | 18 | ||||
-rwxr-xr-x | lib/fuse.c | 5 | ||||
-rw-r--r-- | test/readdir_inode.c | 18 | ||||
-rwxr-xr-x | test/test_examples.py | 14 |
5 files changed, 48 insertions, 9 deletions
diff --git a/ChangeLog.rst b/ChangeLog.rst index 1b75b1d..3e02202 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,3 +1,5 @@ +* Fix returning d_ino and d_type from readdir(3) in non-plus mode + libfuse 3.10.2 (2021-02-05) =========================== diff --git a/example/passthrough.c b/example/passthrough.c index 86ac698..ae13225 100644 --- a/example/passthrough.c +++ b/example/passthrough.c @@ -55,6 +55,8 @@ #include "passthrough_helpers.h" +static int fill_dir_plus = 0; + static void *xmp_init(struct fuse_conn_info *conn, struct fuse_config *cfg) { @@ -132,7 +134,7 @@ static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, memset(&st, 0, sizeof(st)); st.st_ino = de->d_ino; st.st_mode = de->d_type << 12; - if (filler(buf, de->d_name, &st, 0, FUSE_FILL_DIR_PLUS)) + if (filler(buf, de->d_name, &st, 0, fill_dir_plus)) break; } @@ -551,6 +553,18 @@ static const struct fuse_operations xmp_oper = { int main(int argc, char *argv[]) { + enum { MAX_ARGS = 10 }; + int i,new_argc; + char *new_argv[MAX_ARGS]; + umask(0); - return fuse_main(argc, argv, &xmp_oper, NULL); + /* Process the "--plus" option apart */ + for (i=0, new_argc=0; (i<argc) && (new_argc<MAX_ARGS); i++) { + if (!strcmp(argv[i], "--plus")) { + fill_dir_plus = FUSE_FILL_DIR_PLUS; + } else { + new_argv[new_argc++] = argv[i]; + } + } + return fuse_main(new_argc, new_argv, &xmp_oper, NULL); } @@ -3578,6 +3578,11 @@ static int fill_dir_plus(void *dh_, const char *name, const struct stat *statp, } } else { e.attr.st_ino = FUSE_UNKNOWN_INO; + if (statp) { + e.attr.st_mode = statp->st_mode; + if (f->conf.use_ino) + e.attr.st_ino = statp->st_ino; + } if (!f->conf.use_ino && f->conf.readdir_ino) { e.attr.st_ino = (ino_t) lookup_nodeid(f, dh->nodeid, name); diff --git a/test/readdir_inode.c b/test/readdir_inode.c index 7f46c0a..99f95ff 100644 --- a/test/readdir_inode.c +++ b/test/readdir_inode.c @@ -1,7 +1,8 @@ /* - * Prints each directory entry and its inode as returned by 'readdir'. + * Prints each directory entry, its inode and d_type as returned by 'readdir'. * Skips '.' and '..' because readdir is not required to return them and - * some of our examples don't. + * some of our examples don't. However if they are returned, their d_type + * should be valid. */ #include <stdio.h> @@ -30,7 +31,18 @@ int main(int argc, char* argv[]) dent = readdir(dirp); while (dent != NULL) { if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0) { - printf("%llu %s\n", (unsigned long long)dent->d_ino, dent->d_name); + printf("%llu %d %s\n", (unsigned long long)dent->d_ino, + (int)dent->d_type, dent->d_name); + if ((long long)dent->d_ino < 0) + fprintf(stderr,"%s : bad d_ino %llu\n", + dent->d_name, (unsigned long long)dent->d_ino); + if ((dent->d_type < 1) || (dent->d_type > 15)) + fprintf(stderr,"%s : bad d_type %d\n", + dent->d_name, (int)dent->d_type); + } else { + if (dent->d_type != DT_DIR) + fprintf(stderr,"%s : bad d_type %d\n", + dent->d_name, (int)dent->d_type); } dent = readdir(dirp); } diff --git a/test/test_examples.py b/test/test_examples.py index aab970f..880fbad 100755 --- a/test/test_examples.py +++ b/test/test_examples.py @@ -109,7 +109,8 @@ def test_hello(tmpdir, name, options, cmdline_builder, output_checker): umount(mount_process, mnt_dir) @pytest.mark.parametrize("writeback", (False, True)) -@pytest.mark.parametrize("name", ('passthrough', 'passthrough_fh', 'passthrough_ll')) +@pytest.mark.parametrize("name", ('passthrough', 'passthrough_plus', + 'passthrough_fh', 'passthrough_ll')) @pytest.mark.parametrize("debug", (False, True)) def test_passthrough(short_tmpdir, name, debug, output_checker, writeback): # Avoid false positives from libfuse debug messages @@ -124,9 +125,14 @@ def test_passthrough(short_tmpdir, name, debug, output_checker, writeback): mnt_dir = str(short_tmpdir.mkdir('mnt')) src_dir = str(short_tmpdir.mkdir('src')) - cmdline = base_cmdline + \ - [ pjoin(basename, 'example', name), - '-f', mnt_dir ] + if name == 'passthrough_plus': + cmdline = base_cmdline + \ + [ pjoin(basename, 'example', 'passthrough'), + '--plus', '-f', mnt_dir ] + else: + cmdline = base_cmdline + \ + [ pjoin(basename, 'example', name), + '-f', mnt_dir ] if debug: cmdline.append('-d') |