winfsp
winfsp copied to clipboard
FUSE: create called instead of mknod for special files like S_IFIFO
Bug Report
The create callback is called also for special files like S_IFIFO. The special named FIFO file is still not created, instead a corresponding .lnk file pops up in the same directory.
$ mkfifo foobar
$ ls -l foobar*
-rwx------ 1 Hasse None 130 Oct 12 14:46 foobar.lnk*
The same happens if create is not implemented which forces a call to mknod instead. Possible root cause is that the file type mode bits are not being sent properly in create nor mknod callbacks (see issue #256).
I however chose to file this as two separate bugs since they are basically two different deviations compared to the legacy FUSE API behavior on e.g. Linux..
How to Reproduce
This is a bit tricky since you need to mount a user file system that implements the create callback. Then try to create a named FIFO (mkfifo) under some FUSE file system mount point.
Behaviors
According to FUSE documentation, create should only be called for regular files (S_IFREG). From fuse.h:
/** Create a file node
*
* This is called for creation of all non-directory, non-symlink
* nodes. If the filesystem defines a create() method, then for
* regular files that will be called instead.
*/
int (*mknod) (const char *, mode_t, dev_t);
Environment
- OS version and build: CYGWIN_NT-10.0 xxx 3.0.7(0.338/5/3) 2019-04-30 18:08 x86_64 Cygwin
- WinFsp version and build: 2019.2
- fuse2
I did a quick trace and it seems mknod in fact is told to create a file with a ,lnk suffix.
MKNODE /foo.lnk 700
OPEN /foo.lnk 00000a02
Not sure why WinFSP/FUSE does that, mkfifo works just fine in Cygwin outside the mount point. But this is out of scope for this bug, that is, create is called when it should not. I will file a new bug for the mkfifo case and .lnk files unless there is a simple answer to why that happens.
Does WinFSP even know all the file modes defined in POSIX? If I'm not mistaken, Windows defines only a subset in sys/stat.h:
#define _S_IFMT 0xF000 // File type mask
#define _S_IFDIR 0x4000 // Directory
#define _S_IFCHR 0x2000 // Character special
#define _S_IFIFO 0x1000 // Pipe
#define _S_IFREG 0x8000 // Regular
Note the missing constants for block devices (0x6000), symlinks (0xA000) and sockets (0xC000). Or is WinFSP defining them itself?
Edit: Nevermind, I found the answer: WinFSP seems to work with all POSIX modes (including S_IFBLK, S_IFSOCK and S_IFLNK):
https://github.com/winfsp/winfsp/blob/751eaa69dfbb203035208e99aa92693223dac5fe/src/dll/fuse/fuse_intf.c#L494-L521