This is the mail archive of the
mailing list for the Cygwin project.
FUSE, symbolic links and special files
- From: Bill Zissimopoulos <billziss at navimatics dot com>
- To: "cygwin at cygwin dot com" <cygwin at cygwin dot com>
- Date: Thu, 25 Aug 2016 11:46:31 +0000
- Subject: FUSE, symbolic links and special files
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=none (sender IP is ) smtp.mailfrom=billziss at navimatics dot com;
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
While on vacation I have been (slowly) working to add reparse point and
symbolic link support for WinFsp and FUSE for Cygwin. This work is mostly
complete and is currently being tested.
I am writing to the Cygwin list because I want to resolve a problem that
Herbert Stocker originally brought up:
>> [Quick experiment:
>> $ mkfifo foo; cmd /c dir 'foo*' | grep foo; rm foo
>> 06/16/2016 11:02 PM 130 foo.lnk
>> Ok, so they are shortcuts. Naturally they are supported.
> I think they are not.
> The mkfifo system call will have Cygwin create a .lnk file and
> WinFsp will forward it as such to the file system process. The
> sytem calls readdir or open will then have the file system
> process tell WinFsp that there is a .lnk file and Cygwin will
> translate this back to a fifo, so in this sense it does work.
> But the file system will see a file (with name *.lnk) where it
> should see a pipe (mknod call with 'mode' set to S_IFIFO).
> IMHO one could say this is a break of the FUSE API.
> Practically it will break:
> - file systems that special-treat pipe files (or .lnk files).
> - If one uses sshfs to connect to a Linux based server and
> issues the command mkfifo foo from Cygwin, the server will
> end up with a .lnk file instead of a pipe special file.
> - Imagine something like mysqlfs, which stores the stuff in a
> database. When you run SQL statements to analyze the data
> in the file system, you won't see the pipes as such. Or if
> you open the file system from Linux you'll see the .lnk
Herbert is of course right. A .lnk file is not a FIFO to any system other
than Cygwin. I have been thinking about how to solve this problem and I
believe I have an answer in the form of reparse points.
Reparse points can be viewed as a form of special metadata that can be
attached to a file or directory. The interesting thing about reparse
points is that they can have special meaning to a file system driver
(NTFS/WinFsp), a filter driver (e.g. a hierarchical storage system) or
even an application (Cygwin).
NTFS uses reparse points to implement symbolic links and places severe
limitations on them. For one, it differentiates between file and directory
symlinks. It also requires the SE_CREATE_SYMBOLIC_LINK_PRIVILEGE privilege
to be held to create a symbolic link account.
Interestingly it does not perform any extraneous access checks on other
reparse points. IMO this makes reparse points very interesting because it
offers a path for WinFsp and FUSE for Cygwin to provide special file
Turns out that Microsoft already has a solution for special files on NFS:
I see no reason that the same solution cannot be used for FUSE for Cygwin
as well. In the following OP is the originating process, CW is the Cygwin
layer, WL is the WinFsp layer and FL is the FUSE layer.
CW: NtCreateFile, NtDeviceIoControlFile(FSCTL_SET_REPARSE_POINT)
WL: IRP_MJ_FILE_SYSTEM_CONTROL/FSCTL_SET_REPARSE_POINT [NFS_SPECFILE_FIFO]
FL: fuse_operations::mknod("myfifo", S_IFIFO)
Regarding symbolic link support specifically I am still undecided on
whether the right thing to do is to use NTFS symbolic links
(IO_REPARSE_TAG_SYMLINK) or use NFS_SPECFILE_LNK for the FUSE layer. My
inclination is to support both and let the FUSE file system developer
decide on their preference.
Any comments welcome.