mirror of
https://github.com/libfuse/libfuse.git
synced 2024-11-26 21:54:30 +08:00
Fix returning inode numbers from readdir() in offset==0 mode. (#584)
- Test added for all passthrough examples. - passthrough.c uses offset==0 mode. The others don't. - passthrough.c changed to set FUSE_FILL_DIR_PLUS to make the test pass. - This fixes #583.
This commit is contained in:
parent
b9e3ea01db
commit
5012a05ac8
@ -4,6 +4,7 @@ Unreleased Changes
|
||||
* Allow "nonempty" as a mount option, for backwards compatibility with
|
||||
fusermount 2. The option has no effect since mounting over non-empty
|
||||
directories is allowed by default.
|
||||
* Fix returning inode numbers from readdir() in offset==0 mode.
|
||||
|
||||
libfuse 3.10.1 (2020-12-07)
|
||||
===========================
|
||||
|
@ -132,7 +132,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, 0))
|
||||
if (filler(buf, de->d_name, &st, 0, FUSE_FILL_DIR_PLUS))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3566,7 +3566,7 @@ static int fill_dir_plus(void *dh_, const char *name, const struct stat *statp,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (off && statp && (flags & FUSE_FILL_DIR_PLUS)) {
|
||||
if (statp && (flags & FUSE_FILL_DIR_PLUS)) {
|
||||
e.attr = *statp;
|
||||
|
||||
if (!is_dot_or_dotdot(name)) {
|
||||
|
@ -10,6 +10,9 @@ endforeach
|
||||
td += executable('test_syscalls', 'test_syscalls.c',
|
||||
include_directories: include_dirs,
|
||||
install: false)
|
||||
td += executable('readdir_inode', 'readdir_inode.c',
|
||||
include_directories: include_dirs,
|
||||
install: false)
|
||||
|
||||
test_scripts = [ 'conftest.py', 'pytest.ini', 'test_examples.py',
|
||||
'util.py', 'test_ctests.py' ]
|
||||
|
45
test/readdir_inode.c
Normal file
45
test/readdir_inode.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Prints each directory entry and its inode as returned by 'readdir'.
|
||||
* Skips '.' and '..' because readdir is not required to return them and
|
||||
* some of our examples don't.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
DIR* dirp;
|
||||
struct dirent* dent;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: readdir_inode dir\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
dirp = opendir(argv[1]);
|
||||
if (dirp == NULL) {
|
||||
perror("failed to open directory");
|
||||
return 2;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
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);
|
||||
}
|
||||
dent = readdir(dirp);
|
||||
}
|
||||
if (errno != 0) {
|
||||
perror("failed to read directory entry");
|
||||
return 3;
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
|
||||
return 0;
|
||||
}
|
@ -72,6 +72,15 @@ class raii_tmpdir:
|
||||
def short_tmpdir():
|
||||
return raii_tmpdir()
|
||||
|
||||
def readdir_inode(dir):
|
||||
cmd = base_cmdline + [ pjoin(basename, 'test', 'readdir_inode'), dir ]
|
||||
with subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
||||
universal_newlines=True) as proc:
|
||||
lines = proc.communicate()[0].splitlines()
|
||||
lines.sort()
|
||||
return lines
|
||||
|
||||
|
||||
@pytest.mark.parametrize("cmdline_builder", (invoke_directly, invoke_mount_fuse,
|
||||
invoke_mount_fuse_drop_privileges))
|
||||
@pytest.mark.parametrize("options", powerset(options))
|
||||
@ -602,6 +611,10 @@ def tst_readdir(src_dir, mnt_dir):
|
||||
listdir_should.sort()
|
||||
assert listdir_is == listdir_should
|
||||
|
||||
inodes_is = readdir_inode(mnt_newdir)
|
||||
inodes_should = readdir_inode(src_newdir)
|
||||
assert inodes_is == inodes_should
|
||||
|
||||
os.unlink(file_)
|
||||
os.unlink(subfile)
|
||||
os.rmdir(subdir)
|
||||
@ -623,6 +636,10 @@ def tst_readdir_big(src_dir, mnt_dir):
|
||||
listdir_should = sorted(os.listdir(src_dir))
|
||||
assert listdir_is == listdir_should
|
||||
|
||||
inodes_is = readdir_inode(mnt_dir)
|
||||
inodes_should = readdir_inode(src_dir)
|
||||
assert inodes_is == inodes_should
|
||||
|
||||
for fname in fnames:
|
||||
stat_src = os.stat(pjoin(src_dir, fname))
|
||||
stat_mnt = os.stat(pjoin(mnt_dir, fname))
|
||||
@ -631,7 +648,7 @@ def tst_readdir_big(src_dir, mnt_dir):
|
||||
assert stat_src.st_ctime == stat_mnt.st_ctime
|
||||
assert stat_src.st_size == stat_mnt.st_size
|
||||
os.unlink(pjoin(src_dir, fname))
|
||||
|
||||
|
||||
def tst_truncate_path(mnt_dir):
|
||||
assert len(TEST_DATA) > 1024
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user