Visible symlinks under Windows
Corinna Vinschen
corinna at vinschen.de
Thu Feb 21 10:37:07 GMT 2008
Any comment? I'd really have some feedback before I implement something
totally broken.
Thanks,
Corinna
On Feb 14 11:45, Corinna Vinschen wrote:
> To follow up on this... [Beware! It's somewhat long...]
>
> On Feb 7 12:04, Corinna Vinschen wrote:
> > On Feb 6 13:41, James Peach wrote:
> > > With your EA proposal, I think the server would have to restrict symlinks
> > > to be relative to the SMB share and to point to a file within the share.
> > > You'd need this because some clients will follow the symlink on the server,
> > > and some will resolve the target on the client side and you want both
> > > methods to end up at the same place.
> >
> > I guess you're right. Otherwise the non-EA file information returned
> > by calls to ZwQueryInformationFile would point to another file than
> > the symlink path in the EA, and an application trying to access a file
> > gotten by a call to readlink would fail. That sounds rather... medium
> > well.
> >
> > > So, yeh I'm convinced that EA symlinks are worthwhile ...
>
> ...on second thought it turns out that the EAs alone are not very
> helpful as far as the Cygwin side is concerned.
>
> The problem is that the information if EAs are available is only
> accessible when opening the file. This would be a big performance
> problem. Right now, Cygwin only requests file information which is
> available without having to open a file. Only if that information hints
> to a file being a symlink, *then* Cygwin opens the file and retrieves
> the information from the file.
>
> For instance, the old-style faked symlinks on Cygwin have the SYSTEM
> attribute bit set, the new-style symlinks are actually Windows shortcuts
> with the R/O attribute bit set. So the code which tries to figure out
> if a file is a symlink works basically like this:
>
> NtQueryAttributesFile ();
> if (attributes & FILE_ATTRIBUTE_SYSTEM)
> maybe_symlink = true;
> else if ((filename ends in ".lnk") && attributes & FILE_ATTRIBUTE_READONLY)
> maybe_symlink = true;
> if (maybe_symlink)
> {
> NtOpenFile();
> get_symlink_info();
> NtClose();
> }
>
> Assuming we get only the EAs from Samba, we would have to open *every*
> single file on Samba to retrieve EAs:
>
> else if (is_samba ())
> {
> NtOpenFile ();
> NtQueryEaFile ();
> if (has_symlink_ea)
> get_symlink_info();
> NtClose();
> }
>
> I guess the performance hit would be a real show stopper. What we need
> is some way to retrieve file information without having to open the file
> and to get a hint that this file might be a symlink.
>
> Mulling about this problem, I stumbled over the NtQueryFullAttributesFile
> function, which is the NT function retrieving the NT equivalent of the
> SMB_FILE_NETWORK_OPEN_INFORMATION block. It's the maximum amount of
> information available to a Windows client without opening a file. The
> structure consists of
>
> birthtime
> atime
> mtime
> ctime
> allocation_size
> file_size
> dos_attributes
>
> Is it possible to sneak in the information that the file or dir is
> actually a symlink into the above structure?
>
> Two members of this structure are not used by Win32 clients, ctime and
> allocation_size, because the Win32 equivalent of the
> NtQueryFullAttributesFile function, GetFileAttributesEx, does not expose
> them. But ctime is retrieved by Cygwin as... ctime.
>
> So, I had the following idea: Since the allocation_size isn't used
> anyway, what if it simply gets set to st_size?
>
> This would be different from the allocation_size for directories (0)
> as well as different from the allocation_size of files (st_size rounded
> up to some blocksize value) most of the time. That would allow Cygwin
> to retrieve EAs only when it's really a symlink, in 99.9% of the cases.
>
> Does that makes sense?
>
>
> Thanks,
> Corinna
More information about the samba-technical
mailing list