I am seeing a readdir-related problem inside qemu-system-i386, when accessing a '9p' filesystem which is mapped to a host directory. The readdir call does not return any directory entries, not even '.' or '..'. When accessing a local filesystem like /tmp, readdir does return the expected entries. The problem is seen when running Qemu on CentOS 7 with kernel 3.10, and not seen when running the same Qemu version 2.11.0 on Gentoo with kernel 4.14. The target toolchain used to build the test program running inside Qemu is consisting of gcc 7.3.0, glibc 2.28, binutils 2.31.1. Test program takes a directory path as argument and prints out the first three entries received from readdir. In the bad case, this prints nothing. #include <dirent.h> #include <stdio.h> void readonce(DIR *dirp) { struct dirent *d; d = readdir(dirp); if (d == NULL) { printf("no more entries\n"); return; } printf("d_name: %s\n", d->d_name); } int main(int argc, char *argv[]) { DIR *dirp = opendir(argv[1]); for (int i = 0; i < 3 ; i++) { readonce(dirp); } } Output from 'strace -v' on the bad case (accessing the 9p filesystem): openat(AT_FDCWD, "/mnt/nand-dbase/foo/", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3 fstat64(3, {st_dev=makedev(0, 19), st_ino=361311, st_mode=S_IFDIR|0755, st_nlink=2, st_uid=10570, st_gid=3610, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=1545319664 /* 2018-12-20T15:27:44.400824994+0000 */, st_atime_nsec=400824994, st_mtime=1545319674 /* 2018-12-20T15:27:54.205814105+0000 */, st_mtime_nsec=205814105, st_ctime=1545319674 /* 2018-12-20T15:27:54.205814105+0000 */, st_ctime_nsec=205814105}) = 0 brk(NULL) = 0x9da0000 brk(0x9dc1000) = 0x9dc1000 brk(0x9dc2000) = 0x9dc2000 getdents64(3, [{d_ino=361275, d_off=1532808351538279948, d_reclen=24, d_type=DT_DIR, d_name=".."}, {d_ino=358605, d_off=8467452789161523084, d_reclen=24, d_type=DT_REG, d_name="bar"}, {d_ino=361311, d_off=9223372036854775807, d_reclen=24, d_type=DT_DIR, d_name="."}], 32768) = 72 fstat64(1, {st_dev=makedev(0, 6), st_ino=4568, st_mode=S_IFCHR|0600, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_rdev=makedev(4, 65), st_atime=1545319680 /* 2018-12-20T15:28:00.769282559+0000 */, st_atime_nsec=769282559, st_mtime=1545319680 /* 2018-12-20T15:28:00.769282559+0000 */, st_mtime_nsec=769282559, st_ctime=1545313074 /* 2018-12-20T13:37:54.834207421+0000 */, st_ctime_nsec=834207421}) = 0 ioctl(1, TCGETS, {c_iflags=0x1500, c_oflags=0x5, c_cflags=0xcbd, c_lflags=0xa3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x0a\x12\x0f\x17\x16\x00\x00\x00"}) = 0 write(1, "no more entries\n", 16no more entries ) = 16 getdents64(3, [], 32768) = 0 write(1, "no more entries\n", 16no more entries ) = 16 getdents64(3, [], 32768) = 0 write(1, "no more entries\n", 16no more entries ) = 16 Output on the same system but a local filesystem (/tmp): openat(AT_FDCWD, "/tmp/foo", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3 fstat64(3, {st_dev=makedev(0, 15), st_ino=15109, st_mode=S_IFDIR|0755, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=60, st_atime=1545320147 /* 2018-12-20T15:35:47.893535644+0000 */, st_atime_nsec=893535644, st_mtime=1545320150 /* 2018-12-20T15:35:50.597535644+0000 */, st_mtime_nsec=597535644, st_ctime=1545320150 /* 2018-12-20T15:35:50.597535644+0000 */, st_ctime_nsec=597535644}) = 0 brk(NULL) = 0x9f11000 brk(0x9f32000) = 0x9f32000 brk(0x9f33000) = 0x9f33000 getdents64(3, [{d_ino=15109, d_off=1, d_reclen=24, d_type=DT_DIR, d_name="."}, {d_ino=4856, d_off=2, d_reclen=24, d_type=DT_DIR, d_name=".."}, {d_ino=15110, d_off=3, d_reclen=24, d_type=DT_REG, d_name="bar"}], 32768) = 72 fstat64(1, {st_dev=makedev(0, 6), st_ino=4568, st_mode=S_IFCHR|0600, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_rdev=makedev(4, 65), st_atime=1545320152 /* 2018-12-20T15:35:52.769282559+0000 */, st_atime_nsec=769282559, st_mtime=1545320152 /* 2018-12-20T15:35:52.769282559+0000 */, st_mtime_nsec=769282559, st_ctime=1545313074 /* 2018-12-20T13:37:54.834207421+0000 */, st_ctime_nsec=834207421}) = 0 ioctl(1, TCGETS, {c_iflags=0x1500, c_oflags=0x5, c_cflags=0xcbd, c_lflags=0xa3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x0a\x12\x0f\x17\x16\x00\x00\x00"}) = 0 write(1, "d_name: .\n", 10d_name: . ) = 10 write(1, "d_name: ..\n", 11d_name: .. ) = 11 write(1, "d_name: bar\n", 12d_name: bar ) = 12 The bad case shows very large d_off values in getdents64, and repeated calls to this function, while in the good case there is just one call with small d_off values. Could be related to #23960 and/or #23497.
What's the file system on the host that is exported using 9p? Is it ext4? Can you try this with XFS instead? Thanks.
(In reply to Florian Weimer from comment #1) > What's the file system on the host that is exported using 9p? Is it ext4? > > Can you try this with XFS instead? Thanks. I think it is indeed ext4, but the machine is down now for end-of-year maintenance. I will be able to verify it next week. There is no existing XFS filesystem on the machine, but I will try creating an XFS filesystem in a regular file via loop mount. Would it be sufficient for your question?
(In reply to Thomas De Schampheleire from comment #2) > (In reply to Florian Weimer from comment #1) > > What's the file system on the host that is exported using 9p? Is it ext4? > > > > Can you try this with XFS instead? Thanks. > > I think it is indeed ext4, but the machine is down now for end-of-year > maintenance. I will be able to verify it next week. > There is no existing XFS filesystem on the machine, but I will try creating > an XFS filesystem in a regular file via loop mount. Would it be sufficient > for your question? I confirm that the underlying filesystem of the problematic 9p mount is ext4. If I change the underlying filesystem to be xfs (via a loop mount on a file), there is no problem using the test program.
(In reply to Thomas De Schampheleire from comment #3) > (In reply to Thomas De Schampheleire from comment #2) > > (In reply to Florian Weimer from comment #1) > > > What's the file system on the host that is exported using 9p? Is it ext4? > > > > > > Can you try this with XFS instead? Thanks. > > > > I think it is indeed ext4, but the machine is down now for end-of-year > > maintenance. I will be able to verify it next week. > > There is no existing XFS filesystem on the machine, but I will try creating > > an XFS filesystem in a regular file via loop mount. Would it be sufficient > > for your question? > > I confirm that the underlying filesystem of the problematic 9p mount is ext4. > If I change the underlying filesystem to be xfs (via a loop mount on a > file), there is no problem using the test program. The seems to be exactly BZ#23960, I will mark is as duplicated. *** This bug has been marked as a duplicate of bug 23960 ***