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 - was: Re: Fork and Windows Heap

Hi, Corinna:

On Jun 17 07:25, Bill Zissimopoulos wrote:
> > Windows hard links are rather un-POSIX like and rarely used on Windows.
> > After considering the required changes on the FSD for a feature that is
> > so rarely used I opted against supporting them.
> I disagree here.  Windows hardlinks work fine and pretty much as on
> POSIX with the exception of DOS mode bits.  Those are not per file but
> per file entry as far as my experiecen goes.  One of the reasons we try
> to ignore them as much as possible.

I no longer remember all the details now, because it was a few months ago
that I looked into this and determined that hard links are "un-POSIX like".
As far as I recall there was the FileAttributes issue (which I now think
may have been my incorrect understanding of the documentation), but there
was also the issue of FindFirstFileName/FindNextFileName, which is not
something that POSIX supports out of the box (AFAIK).

Regarding the FileAttributes issue. The Windows documentation seems to
suggest that they are stored with the file and not the directory entry.
I have not experimented though to confirm whether this is true.

From MSDN "Hard Links and Junctions" [1]:
Note that the attributes on the file are reflected in every hard link
to that file, and changes to that file's attributes propagate to all
the hard links. For example if you reset the READONLY attribute on a
hard link to delete that particular hard link, and there are multiple
hard links to the actual file, then you will need to reset the READONLY
bit on the file from one of the remaining hard links to bring the file
and all remaining hard links back to the READONLY state.

And then of course there is this ambiguous bit:
However, the directory entry size and attribute information is updated
only for the link through which the change was made.

I think that attribute information in this case means "NTFS attribute"
and not FILE_ATTRIBUTE_*. NTFS attributes are simply the method that
NTFS uses to store information about files.

Taken together this information suggests that NTFS hard links are more
"POSIX like" than I thought. In fact they may be "POSIX like with extra

The bigger issue is that the FSD now maintains an internal table of open
files that is indexed by file name. It actually started as a table of open
files indexed by IndexNumber (inode number Windows equivalent), but I
eventually had to change it for a number of issues (notably Rename
support). I am not saying that it would not be possible to change this
part of WinFsp, I just believe that it is a non-trivial change at this

> > > You write that you are mapping
> > >  - characters not supported by Win32 but by POSIX via the Unicode
> > >    private use page
> > >  - Security apspects (SID vs. uid/gid, ACL)
> > > between POSIX and Windows and that you do it like Cygwin/SFU/SFM is
> > > doing it.
> Uhm... I don't understand.  Cygwin is using the private unicode range as
> well to map characters invalid in a Windows filename (e.g. colon 0x3a is
> mapped to 0xf03a).  This is how such filenames are given to the OS
> This means, WinFsp would get these filenames from a Cygwin process
> already in the transposed form, with invalid FS chars transposed into the
> private area.
> If WinFsp would support that, it would be transparent to applications
> with very minor effort.

I think I may have inadequately explained what WinFsp does with this
mapping. It basically does the opposite of what Cygwin does on any given
code path.

Let's examine the lifetime of a call to creat(). Suppose a Cygwin process
does creat("/cygdrive/z/foo*bar"). 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".

OP: creat("/cygdrive/z/foo*bar")
CW: NtCreateFile(L"<DEVICE>\\foo\xf02abar")     <--- Cygwin translation
NT: IRP_MJ_CREATE L"\\foo\xf02abar"
WD: FspFsctlTransactCreateKind L"\\foo\xf02abar"
WL: FSP_FILE_SYSTEM_INTERFACE::Create L"\\foo\xf02abar"
FL: fuse_operations::create "/foo*bar"          <--- WinFsp/FUSE
FS: somehow satisfies fuse_operations::create
[snip return path]

The opposite happens when the file system communicates a file name back
to the originating process, as in readdir().

OP: readdir("/cygdrive/z/")
[snip call path]
FS: fuse_operations::readdir response: "foo*bar"
FL: FSP_FILE_SYSTEM_INTERFACE::ReadDirectory response: L"foo\xf02abar"
WL: FspFsctlTransactQueryDirectoryKind response: L"foo\xf02abar"
WD: IRP_MN_QUERY_DIRECTORY response: L"foo\xf02abar"
NT: NtQueryDirectoryFile response: L"foo\xf02abar"
CW: readdir response: "foo*bar"
OP: receives "foo*bar"

Now also recall that native Windows is my primary target environment and
that the originating process will likely not be a Cygwin process. Suppose
that SSHFS is used to mount a directory that has a "foo*bar" file. How to
present that to a Win32 process? I hope that this makes the need for the
WinFsp mapping more apparent.



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