summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.rst2
-rw-r--r--example/passthrough.c18
-rwxr-xr-xlib/fuse.c5
-rw-r--r--test/readdir_inode.c18
-rwxr-xr-xtest/test_examples.py14
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);
}
diff --git a/lib/fuse.c b/lib/fuse.c
index 737456e..a95d7c1 100755
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -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')