virtio-win / kvm-guest-drivers-windows

Windows paravirtualized drivers for QEMU\KVM
https://www.linux-kvm.org/page/WindowsGuestDrivers
BSD 3-Clause "New" or "Revised" License
1.99k stars 382 forks source link

virtio-fs: Unable to remove empty directory #497

Closed kevinoid closed 4 years ago

kevinoid commented 4 years ago

When sharing a host directory with a Windows 10 guest via virtio-fs using viofs.sys and virtiofs.exe from virtio-win-0.1.189.iso and WinFSP 2020.1, when I run the following from a command prompt (assuming the virtio-fs directory is mounted as z: in the guest and initially empty):

z:
md foo
rd foo

It prints:

The directory is not empty.

and the directory is not removed. This behavior occurs when the host directory is ext4 or ntfs-3g, but not tmpfs.

virtiofs.exe -d -1 debug log *** VirtFsFuseRequest: >>req: 26 unique: 2 len: 56 *** VirtFsFuseRequest: <>QueryVolumeInformation *** VirtFsFuseRequest: >>req: 17 unique: 3 len: 40 *** VirtFsFuseRequest: <>Create [UT---C] "\", FILE_OPEN, CreateOptions=200000, FileAttributes=0, Security=NULL, AllocationSize=0:0, AccessToken=000000000000025C[PID=13a8], DesiredAccess=80, GrantedAccess=0, ShareAccess=7 *** GetSecurityByName: "\" *** VirtFsFuseRequest: >>req: 1 unique: 4 len: 42 *** VirtFsFuseRequest: <>req: 1 unique: 5 len: 42 *** VirtFsFuseRequest: <>req: 27 unique: 6 len: 48 *** VirtFsFuseRequest: <>Close 0000000000000000:000001A78E9FC570 *** Close: fh: 4 nodeid: 3 *** VirtFsFuseRequest: >>req: 29 unique: 7 len: 64 *** VirtFsFuseRequest: <>Create [UT---C] "\", FILE_OPEN, CreateOptions=21, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=0000000000000260[PID=9b0], DesiredAccess=100000, GrantedAccess=0, ShareAccess=3 *** GetSecurityByName: "\" *** VirtFsFuseRequest: >>req: 1 unique: 8 len: 42 *** VirtFsFuseRequest: <>req: 1 unique: 9 len: 42 *** VirtFsFuseRequest: <>req: 27 unique: 10 len: 48 *** VirtFsFuseRequest: <>QueryVolumeInformation *** VirtFsFuseRequest: >>req: 17 unique: 11 len: 40 *** VirtFsFuseRequest: <>Close 0000000000000000:000001A78E9FC2A0 *** Close: fh: 4 nodeid: 3 *** VirtFsFuseRequest: >>req: 29 unique: 12 len: 64 *** VirtFsFuseRequest: <>Create [UT---C] "\", FILE_OPEN, CreateOptions=21, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=000000000000025C[PID=9b0], DesiredAccess=100020, GrantedAccess=0, ShareAccess=3 *** GetSecurityByName: "\" *** VirtFsFuseRequest: >>req: 1 unique: 13 len: 42 *** VirtFsFuseRequest: <>req: 1 unique: 14 len: 42 *** VirtFsFuseRequest: <>req: 27 unique: 15 len: 48 *** VirtFsFuseRequest: <>Create [UT---C] "\foo", FILE_CREATE, CreateOptions=200021, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=000000000000025C[PID=9b0], DesiredAccess=100001, GrantedAccess=0, ShareAccess=3 *** GetSecurityByName: "\" *** VirtFsFuseRequest: >>req: 1 unique: 16 len: 42 *** VirtFsFuseRequest: <>req: 9 unique: 17 len: 52 *** VirtFsFuseRequest: <>Cleanup 0000000000000000:000001A78E9FC420 *** Cleanup: "" Flags: 0x22 virtiofs[TID=17c4]: FFFF830F0DB564A0: <>Close 0000000000000000:000001A78E9FC420 *** Close: fh: 18446744073709551615 nodeid: 2 *** VirtFsFuseRequest: >>req: 29 unique: 18 len: 64 *** VirtFsFuseRequest: <>Create [UT---C] "\foo", FILE_OPEN, CreateOptions=200021, FileAttributes=10, Security=NULL, AllocationSize=0:0, AccessToken=0000000000000260[PID=9b0], DesiredAccess=110080, GrantedAccess=0, ShareAccess=7 *** GetSecurityByName: "\foo" *** VirtFsFuseRequest: >>req: 1 unique: 19 len: 44 *** VirtFsFuseRequest: <>req: 1 unique: 20 len: 44 *** VirtFsFuseRequest: <>req: 27 unique: 21 len: 48 *** VirtFsFuseRequest: <>SetInformation [Disposition] "\foo", 0000000000000000:000001A78E9FC420, Delete *** GetFileInfo: fh: 5 nodeid: 2 *** VirtFsFuseRequest: >>req: 3 unique: 22 len: 56 *** VirtFsFuseRequest: <>req: 3 unique: 23 len: 56 *** VirtFsFuseRequest: <>Close 0000000000000000:000001A78E9FC420 *** Close: fh: 5 nodeid: 2 *** VirtFsFuseRequest: >>req: 29 unique: 24 len: 64 *** VirtFsFuseRequest: <

I have been unable to reproduce the behavior using Alpine Linux, so I suspect the issue is in the guest, rather than the host.

Thanks for creating/supporting these drivers! Let me know if there is anything else I can do to help debug.

Thanks again, Kevin

hammerg commented 4 years ago

Nice catch (I only used tmpfs until now). I assume the problem is with the logic that test if a directory is empty (I check for the directory "file" size which is probably not the right way to do it).

kevinoid commented 4 years ago

Thanks @hammerg! The fix looks great. Are there any publicly available snapshot builds that I could test, or would I need to build+sign myself?