Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WSL2: Seek of directory entry by lseek does not work on v9fs #5074

Open
ngyuki opened this issue Apr 11, 2020 · 18 comments
Open

WSL2: Seek of directory entry by lseek does not work on v9fs #5074

ngyuki opened this issue Apr 11, 2020 · 18 comments

Comments

@ngyuki
Copy link

ngyuki commented Apr 11, 2020

Build number: Microsoft Windows [Version 10.0.19603.1000]

Seek of directory entry by lseek does not work on v9fs.

Code: a.c

#define _GNU_SOURCE
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>

struct linux_dirent {
    long           d_ino;
    off_t          d_off;
    unsigned short d_reclen;
    char           d_name[];
};

#define BUF_SIZE 1024

int main()
{
    int fd, nread;
    char buf[BUF_SIZE];
    struct linux_dirent *d;
    off_t off;
    int bpos;

    fd = open("./xxx/", O_RDONLY | O_DIRECTORY);
    syscall(SYS_getdents, fd, buf, BUF_SIZE);
    off = lseek(fd, 0, SEEK_SET);
    if (off < 0) {
        return 1;
    }

    while ((nread = syscall(SYS_getdents, fd, buf, BUF_SIZE)) > 0) {
        for (bpos = 0; bpos < nread;) {
            d = (struct linux_dirent *)(buf + bpos);
            printf("%s\n", d->d_name);
            bpos += d->d_reclen;
        }
    }
    return 0;
}

Prepare directory and running

mkdir ./xxx/
seq -w 0000001 0000040 | xargs -i touch ./xxx/{}.txt
ls xxx/ | wc -l
#=> 40

gcc a.c
./a.out | sort

Actual output

0000031.txt
0000032.txt
0000033.txt
0000034.txt
0000035.txt
0000036.txt
0000037.txt
0000038.txt
0000039.txt
0000040.txt

Expected output

.
..
0000001.txt
0000002.txt
0000003.txt
0000004.txt
0000005.txt
0000006.txt
0000007.txt
0000008.txt
0000009.txt
0000010.txt
0000011.txt
0000012.txt
0000013.txt
0000014.txt
0000015.txt
0000016.txt
0000017.txt
0000018.txt
0000019.txt
0000020.txt
0000021.txt
0000022.txt
0000023.txt
0000024.txt
0000025.txt
0000026.txt
0000027.txt
0000028.txt
0000029.txt
0000030.txt
0000031.txt
0000032.txt
0000033.txt
0000034.txt
0000035.txt
0000036.txt
0000037.txt
0000038.txt
0000039.txt
0000040.txt

On ext4 we get the expected result.

Strace

execve("./a.out", ["./a.out"], 0x7ffdc9af5ce0 /* 20 vars */) = 0
brk(NULL)                               = 0x556e019c6000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=25456, ...}) = 0
mmap(NULL, 25456, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe00ba2c000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe00ba2a000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe00b41b000
mprotect(0x7fe00b602000, 2097152, PROT_NONE) = 0
mmap(0x7fe00b802000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7fe00b802000
mmap(0x7fe00b808000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe00b808000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7fe00ba2b4c0) = 0
mprotect(0x7fe00b802000, 16384, PROT_READ) = 0
mprotect(0x556e0166a000, 4096, PROT_READ) = 0
mprotect(0x7fe00ba33000, 4096, PROT_READ) = 0
munmap(0x7fe00ba2c000, 25456)           = 0
openat(AT_FDCWD, "./xxx/", O_RDONLY|O_DIRECTORY) = 3
getdents(3, /* 32 entries */, 1024)     = 1008
lseek(3, 0, SEEK_SET)                   = 0
getdents(3, /* 10 entries */, 1024)     = 320
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
brk(NULL)                               = 0x556e019c6000
brk(0x556e019e7000)                     = 0x556e019e7000
write(1, "0000031.txt\n", 120000031.txt
)           = 12
write(1, "0000032.txt\n", 120000032.txt
)           = 12
write(1, "0000033.txt\n", 120000033.txt
)           = 12
write(1, "0000034.txt\n", 120000034.txt
)           = 12
write(1, "0000035.txt\n", 120000035.txt
)           = 12
write(1, "0000036.txt\n", 120000036.txt
)           = 12
write(1, "0000037.txt\n", 120000037.txt
)           = 12
write(1, "0000038.txt\n", 120000038.txt
)           = 12
write(1, "0000039.txt\n", 120000039.txt
)           = 12
write(1, "0000040.txt\n", 120000040.txt
)           = 12
getdents(3, /* 0 entries */, 1024)      = 0
exit_group(0)                           = ?
+++ exited with 0 +++
@ngyuki
Copy link
Author

ngyuki commented Apr 11, 2020

The following code reproduces the same problem.

#include <stdio.h>
#include <dirent.h>

int main() {
    DIR *dh;
    struct dirent *de;

    dh = opendir("./xxx/");
    readdir(dh);

    rewinddir(dh); // does not work

    while (de = readdir(dh)) {
        printf("%s\n", de->d_name);
    }

    return 0;
}
seq -w 0000001 0001030 | xargs -i touch ./xxx/{}.txt

ls xxx/ | wc -l
#=> 1030

gcc a.c
./a.out | sort
#=> 0001023.txt
#=> 0001024.txt
#=> 0001025.txt
#=> 0001026.txt
#=> 0001027.txt
#=> 0001028.txt
#=> 0001029.txt
#=> 0001030.txt

@therealkenc
Copy link
Collaborator

Nice post. Confirmed WSL2 19603.

As a work-around, I confirmed cifs is okay. You'll have to do without metadata though, natch.

image

Something like:

$ sudo apt install cifs-utils
$ mkdir ./mnt
$ sudo mount -t cifs -o username=you //xxx.xxx.xxx.xxx/Users/you ./mnt

@themizzi
Copy link

themizzi commented Oct 13, 2020

Curious why this is closed since it does not seem to have been repaired. PHP maintainers believe this is the cause of the following issue: #6081 which affects Docker for Desktop and makes this a chore. Is there any appetite to fix this with v9fs? I do not see a bug in the v9fs bug tracker regarding this. Thanks! Any update is appreciated!

https://bugs.php.net/bug.php?id=80227

@Zenexer
Copy link

Zenexer commented Oct 29, 2020

Any update on this? This breaks popular PHP applications that are likely to be run in WSL2 for development purposes, including XenForo.

@SeniorSupportEngineer
Copy link

I got problems with phpunit that does not discover all test files in a large directory. Find it strange that this still isn't fixed.

@VeselyJan92
Copy link

Suggestion: If wouldn't mind using VSCode it's actually better fully switch development into WSL and use VSCode as frontend editor more on that here. There is no overhead between translating different file systems and works like a charm and there is no speed/ram/cpu overhead. I am running a PHP docker app with its code sticking out for development.

@stevennight
Copy link

Any bro has been resolved?
I try to run the swoft project on docker on Windows, but some file can not read when loading.

@SailorMax
Copy link

SailorMax commented Jul 31, 2022

Same problem with symfony/finder class, which uses php's RecursiveDirectoryIterator class.

@dacgray
Copy link

dacgray commented Aug 30, 2022

Same problem when using squizlabs/php_codesniffer

@ReWiG
Copy link

ReWiG commented Sep 29, 2022

Confirming the same issue with phpunit/phpunit and zircote/swagger-php
Windows 10 Pro 21H2

@Zenexer
Copy link

Zenexer commented Sep 29, 2022

Could we add a bug label to this?

@Zenexer
Copy link

Zenexer commented Apr 11, 2023

@benhillis, could you put a bug label on this so it doesn't get lost? This is a pretty serious issue that prevents quite a bit of software from working within WSL2, including PHP.

@Ador-able
Copy link

I have encountered the same problem. Has the error from 3 years ago not been fixed yet

@NathanBaulch
Copy link

Still preventing me from launching docker containers with Windows FS volume mounts 😞, it's been years now.

@selfer-work
Copy link

I needed to set up my project for emergencies on a laptop. However this bug makes Docker Desktop on Windows 11 Home edition unusable when combining it with PHPStorm. Simple solution on Windows 11 Pro edition is to switch to Hyper-V. But no, for some reason you can't do that in Home edition. So no point in using Windows for me I guess.

@SeniorSupportEngineer
Copy link

SeniorSupportEngineer commented Aug 18, 2023

@selfer-work That is why I switch to the Ubuntu app and now I'am using projector, phpstorm runs in projector in ubuntu, the client in windows uses the weblink. And yes it is not ideal. Works better than the windows for docker. And much faster phpunit testing.

@Mattie112
Copy link

(a quick "fix" is to put all source files "in" WSL, then open that directory in your PhpStorm (or whatever), the WSL files should be available at \wsl.local if I am not mistaking)

@SailorMax
Copy link

"dev drive" also can be used as "quick fix" for this problem: https://learn.microsoft.com/en-us/windows/dev-drive/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests