This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: FUSE for Cygwin


Hi, Herbert:


On 6/19/16, 4:20 AM, "cygwin-owner@cygwin.com on behalf of Herbert
Stocker" <cygwin-owner@cygwin.com on behalf of hersto@gmx.de> wrote:

>this is now my proposal of an alternative mode for WinFsp to support
>Cygwin based FUSE file systems. I'll call it mode (4)...
>
>To repeat your 3 modes of operation (in my words):...
>
>(3) The file system is a Cygwin process and thus can use all POSIX
>     features of Cygwin. It needs no porting or only little.
>
>What i don't like on (3) is that when a Cygwin process accesses the
>FUSE file system there are two Cygwin processes whose communication
>is translated from Posix to Win32 and then back (which is done again
>for the response).

Actually I do not believe this is the case. Let me show again the complete
path of a creat() request, this time with context switches.

As before in the following OP is the âoriginating process", CW is the
"Cygwin runtime", NT is NTOS, WD is the "WinFsp FSDâ, WL is the "WinFsp
DLL", FL is the "FUSE layer", and FS is the "user mode FUSE file system".

==== RUNNING in OP context
OP: call creat("/cygdrive/z/foo*bar")
CW: call NtCreateFile(L"<DEVICE>\\foo\xf02abarâ)
NT: call IRP_MJ_CREATE L"\\foo\xf02abar"
WD: post FspFsctlTransactCreateKind L"\\foo\xf02abarâ
==== SWITCH to FS context
WL: recv FspFsctlTransactCreateKind,
    call FSP_FILE_SYSTEM_INTERFACE::Create L"\\foo\xf02abar"
FL: call fuse_operations::create "/foo*bar"
FS: somehow satisfies fuse_operations::create

FS: return errno=0,
    fuse_file_info::fh
FL: return STATUS_SUCCESS,
    FSP_FSCTL_TRANSACT_RSP::Rsp.Create.Opened.UserContext2
WL: return STATUS_SUCCESS,
    FSP_FSCTL_TRANSACT_RSP::Rsp.Create.Opened.UserContext2
WD: complete IRP_MJ_CREATE with
    STATUS_SUCCESS, NTOS FILE_OBJECT properly initialized
==== SWITCH to OP context
NT: return STATUS_SUCCESS,
    HANDLE opened by NTOS for FILE_OBJECT
CW: return fd for HANDLE just opened, (maybe?) set errno=0

As you can see there are only two context switches. The only two processes
involved are OP (the originating process) and FS (the user mode file
system).

[BTW, a WinFsp file system process is able to process multiple requests in
the same thread without a context switch, but from the perspective of an
OP there will be (at least) 2 context switches for a creat() response to
complete.]


>So my proposal is basically this:
>
>(4) The file system is a Cygwin process and Cygwin is extended to
>     pass file system requests to that process if they fall into the
>     respective path (where the file system is mounted.)
>
>     This way the file system is exported to Cygwin only. But another
>     tool exports this to the Win32 world.

It is my understanding from my brief foray into the Cygwin source that
Cygwin already has the fhandler mechanism, which looks like a natural
place to implement a Cygwin-only FUSE for Windows.

>Mode (4) would avoid the following issues coming from the double
>translation of mode (3):
>
>A) Besides the double double translations of every request, there
>    is also the need for four Kernel/Usermode transitions, which take
>    their time.

As explained, there are 2 context switches and not 4. If you had an
fhandler that somehow calls out into a FUSE file system, it would still
need to do 2 context switches (one to get the request to the FUSE file
system and one to get the response back).

The POSIX/Windows translations are actually not that expensive, although
they are not trivial (creating a security descriptor requires memory
allocations). But of course the dominant factor here is the context switch.

>C) i guess this way we could support fuse with all other languages
>    besides C/C++.

BTW, I already had some luck last night getting FUSEPY to work with
WinFsp. I should have something out on this soon.

>E) Same for uid/gid to SID mapping.
>    No need to implement or follow Cygwin.
>    And how about the case where a uid/gid has no correspoinding SID?
>    Can this happen?

Yes, it can, but this is an issue that Cygwin faces itself.

>F) Pipes:
> > [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.

Good catch this one!

Of course I can try to fix this in the WinFsp/FUSE layer implementation,
but the fix would probably be a gross and Cygwin-specific hack. But
definitely good catch!

>    To fix this with mode (3) you'd have to recognize these .lnk
>    files and forward them to the file system as pipes, and you'd
>    have to generate .lnk files on the fly when the file system
>    says there is a pipe file (e.g. on readdir).

Yes, I agree. Not pretty!

>G) Case sensitivity.
>    Windows is usually case insensitive but case
>    preserving on file names...
>
>    What happens if you use sshfs to connect to a Linux box and then
>    do the following in cmd.exe:
>      # echo Hallo >Foo.txt
>      # type foo.Txt

WinFsp (and Windows) allows for both case-sensitive and case-insensitive
file systems. I only have OSX currently to SSH into (which is
case-insensitive) so I cannot run your experiment. But I expect that the
"type" command would not work, because FUSE file systems are marked as
case-sensitive by default (or I have a bug in WinFsp).

>It looks like mode (4) is much more work because it requires FUSE
>to be reimplemented/ported to Cygwin. But it's lesser work on WinFsp
>and would have no issues due to double translations. It would make
>Cygwin processes 1st class on FUSE file systems.

Just to clarify: I believe that Cygwin processes are already on the same
class as Win32 processes when it comes to a WinFsp exposed file system.
There are no extra context switches and the only translations required are
those that Cygwin does for its POSIX layer and against the existing
Windows file systems (like NTFS).

IMO getting a FUSE for (just) Cygwin should be relatively easy using the
fhandler mechanism (disclaimer: I am no expert in the Cygwin source and
have probably spent a total of an hour or two on it). IMO it would also be
desirable.

OTOH you would also lose the ability to easily port FUSE file systems to
*all* of Windows, which (at least for me) has been the primary reason for
doing this work. Even if you created an intermediate Cygwin process (that
acted as a WinFsp file system) to let Win32 processes access these FUSE
file systems, you would now make those Win32 processes 2nd class citizens,
as they would have to go through that intermediate process (which means 4
context switches per file system request for them).

Bill


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]