Bug 5209 - Wrong inode numbers/FileIndex and other problems with symlinks
Summary: Wrong inode numbers/FileIndex and other problems with symlinks
Status: NEW
Alias: None
Product: Samba 3.0
Classification: Unclassified
Component: File Services (show other bugs)
Version: 3.0.28
Hardware: All Linux
: P3 normal
Target Milestone: none
Assignee: Samba Bugzilla Account
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-01-17 08:06 UTC by Corinna Vinschen
Modified: 2008-02-13 02:40 UTC (History)
0 users

See Also:


Attachments
Preliminary patch to use lstat for Windows clients (5.53 KB, text/plain)
2008-02-13 02:40 UTC, Corinna Vinschen
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Corinna Vinschen 2008-01-17 08:06:33 UTC
When a Windows client fetches file information from Samba, then Samba always
uses stat(2) instead of lstat(2), that way resolving symlinks to their target
if it exists.  That's fine for the normal content of the file information
given to Windows clients, which don't understand symlinks.

However, there are a couple of problems with this.  For instance, consider the
following situation on the Samba side:

Samba$ mkdir -p ~/tmp/test
Samba$ cd ~/tmp/test
Samba$ mkdir subdir
Samba$ ln -s subdir symlink

When using Cygwin on the Windows side, the FileIndex returned by Samba is used
as the i-node number of the file.  When calling ls -li from Cygwin, something
like this is printed:

Cygwin$ ls -li //samba-box/tmp/test
total 0
8808978157900 drwxr-xr-x 1 corinna root 0 Jan 15 14:46 subdir
8808978157900 drwxr-xr-x 1 corinna root 0 Jan 15 14:46 symlink

So, we have two directories with the same i-node number.  If you try to copy
these files under Cygwin from the Samba share to a local directory, cp(1)
from recent coreutils will print:

Cygwin$ cp -rp //samba-box/tmp/test .
cp: will not create hard link `./test/symlink' to directory `./test/subdir'

Another problem occurs if you try to delete the parent directory from Cygwin:

Cygwin$ cd //samba-box/tmp
Cygwin$ rm -rf test
rm: cannot remove directory `test': Directory not empty
Cygwin$ cd test
ls -a
.  ..

Huh?  Let's see how this looks like on the Samba side:

Samba$ ls -l ~/tmp/test
total 0
lrwxrwxrwx 1 corinna users 6 Jan 15 14:47 symlink -> subdir

This is not only a problem in Cygwin.  Using Windows explorer to delete
the symlink results in a dialog(*):

"Are you sure you want to remove the folder 'symlink' and all its contents?"

After confirming you'll get another dialog:

"Cannot remove the folder symlink: Directory name invalid."

Anyway, the intransparency of symlinks is a real problem.  It looks like
both problems could be solved like this:  Always call lstat(2) first.  Only
call stat(2) afterwards if it's a symlink, and only call it to find out
if it's a file or a directory, to set the file type correctly for the reply
to Windows.
In calls which manipulate files, manipulate the symlink itself, never the
target.  That means, deleting a symlink from Windows should also only
delete the symlink, not the target file or directory.

If this is something to consider, I'd gladly help out with code.


Corinna

(*) Related to this problem I found
    https://bugzilla.samba.org/show_bug.cgi?id=4536,
    but the solution doesn't seem to be in 3.0.28.  Or was that somehow a
    different situation?
Comment 1 Jeremy Allison 2008-02-12 20:22:00 UTC
The problem with this solution is that it doubles the number of [l]stat calls in the common case (Windows clients accessing). This would cause a performance problem for us.

The POSIX solution for this is to use the UNIX extensions trans2 calls, but being stuck on Windows you don't get to select the calls the redirector makes.

Handling of symlinks from Windows clients is not currently ideal. Let me think about this some more.

Jeremy.
Comment 2 Corinna Vinschen 2008-02-13 02:39:43 UTC
I'm not convinced using lstat results in a big performance hit.  For 
every non-symlink file, the number of calls is still one.  You only need
a single lstat call in the common case, and only for symlinks you need
another call to stat.  I attached a preliminary patch against the
3.2-test repo to this bug.

OTOH, this approach does still not allow to identify symlinks from 
Cygwin so it helps only marginally.  That's why I proposed to add
symlink information in EAs in

http://lists.samba.org/archive/samba-technical/2008-February/057818.html

However, this EA approach alone has the disadvantage to slow down 
Cygwin, because it would require to retrieve EAs for every file from a
Samba share to see if a symlink EA is available.  This is not such a
good solution unless we have another trick to guess on a file being a
symlink from the SMB_FILE_NETWORK_OPEN_INFORMATION block.
Maybe we can set the allocation size to some distinct value?!?


Corinna
Comment 3 Corinna Vinschen 2008-02-13 02:40:44 UTC
Created attachment 3139 [details]
Preliminary patch to use lstat for Windows clients