GNOME Bugzilla – Bug 795805
Copying file to Windows server (SMB2) via gvfsd-fuse and gvfsd-smb fails with EINVAL
Last modified: 2018-05-14 12:14:14 UTC
Created attachment 371673 [details] GVFS_DEBUG=10 GVFS_DEBUG_FUSE=10 GVFS_SMB_DEBUG=10 /usr/lib/gvfs/gvfsd --replace -d 2>&1 If a share on a Windows file server (not a Samba server) is mounted and uses the SMB2 protocol, any attempt to copy or create a file for writing (e.g. using the cp or cat commands from the bash shell) on the mount point via FUSE will create a zero-length file but the open will return with an EINVAL error. Copying files via Nautilus works. The problem seems to be due to the SMB2 GetInfo request with info level SMB2_FILE_ALL_INFO (which is issued by the vfs_getaddr handler just after a successful SMB2 Create Request for the file) being responded to with a STATUS_ACCESS_DENIED error. This is normal for a Windows server when the file is opened write-only. In contrast, a Samba server will process the request SMB2 GetInfo request successfully for a write-only file. Copying a file via Nautilus works because it writes the file contents before issuing the SMB GetInfo request. Software versions (Debian GNU/Linux): * linux-image-4.15.0-3-amd64 4.15.17-1 * gvfs-daemons 1.36.1-1 * gvfs-fuse 1.36.1-1 * gvfs-backends 1.36.1-1 * libsmbclient 2:4.7.4+dfsg-2 Windows server version: Hyper-V Core Server 2012 R2
Created attachment 371674 [details] Wireshark capture
FYI, an SMB2 GetInfo request with info level SMB2_FILE_ALL_INFO (these are as displayed by Wireshark) is officially called an SMB2 QUERY_INFO request with InfoType = SMB2_0_INFO_FILE and FileInfoClass = FileAllInformation. The request failed because the SMB2 Create request's DesiredAccess bitmask did not have the FILE_READ_ATTRIBUTES bit set.
Thanks for your report, so O_RDWR instead O_WRONLY should fix it for Windows servers, shouldn't it? Can you please test that the following patch fixes the issue for you? I hope that O_RDWR doesn't have some limitations...
Created attachment 371836 [details] [review] smb: Use O_RDWR to fix fstat when writing fstat fails with EINVAL on Windows servers if O_WRONLY is used to open (though it works properly on SAMBA servers). O_RDWR is needed to make it work. This causes issues when copying files over gvfsd-fuse among others.
Thanks for the patch, it seems to work fine[*], although I don't know if changing O_WRONLY to O_RDWR would cause issues elsewhere. [*] I applied the patch to the gnome-3-28 branch rather than the master branch as it was easier to sort out the dependencies on my Debian testing system that way. I couldn't figure out how to run gvfsd-smb from the build directory manually properly, so I backed up my original /usr/lib/gvfs/gvfsd-smb and overwrote it with the test version. (I also had to install libgvfscommon.so and libgvfsdaemon.so into /usr/local/lib and run ldconfig.) I will attach the relevant part of the log for the part where I copied a test file to the Windows server.
Created attachment 371901 [details] gvfsd log after applying "smb: Use O_RDWR to fix fstat when writing" patch This is the portion of the output from `GVFS_DEBUG=10 GVFS_DEBUG_FUSE=10 GVFS_SMB_DEBUG=10 /usr/lib/gvfs/gvfsd --replace -d 2>&1` (after patching gvfsd-smb) related to copying the file `foo.txt` to the server. As can be seen, the two 'vfs_getattr' requests (for file 'foo.txt') before the vfs_create fail because a remote file with that name does not exist (I don't know why there is more than one 'vfs_getattr' request!). The 'vfs_create' succeeds, and the 'vfs_getattr' after the 'vfs_create' now succeeds where it was failing before the patch was applied. Differences in file creation parameters.... Before patch: map_open_params_to_ntcreate: fname = \foo.txt, deny_mode = 0x41, open_func = 0x10 map_open_params_to_ntcreate: file \foo.txt, access_mask = 0x120116, share_mode = 0x3, create_disposition = 0x2, create_options = 0x40 private_flags = 0x0 After patch: map_open_params_to_ntcreate: fname = \foo.txt, deny_mode = 0x42, open_func = 0x10 map_open_params_to_ntcreate: file \foo.txt, access_mask = 0x12019f, share_mode = 0x3, create_disposition = 0x2, create_options = 0x40 private_flags = 0x0
Thanks for testing, hopefuly, it won't break anything else. Attachment 371836 [details] pushed as 3f6f906 - smb: Use O_RDWR to fix fstat when writing I am going to push in gnome-3-28 as well.