Bug 3529 - Hardlink count for directories incorrect... most of the time
Hardlink count for directories incorrect... most of the time
Status: RESOLVED FIXED
Product: Samba 3.0
Classification: Unclassified
Component: File Services
3.0.21b
x64 Linux
: P3 normal
: none
Assigned To: Samba Bugzilla Account
Samba QA Contact
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2006-02-20 10:20 UTC by Corinna Vinschen
Modified: 2008-01-18 19:45 UTC (History)
1 user (show)

See Also:


Attachments
Windows testcase for hardlink count on Samba shares (1.90 KB, text/plain)
2006-02-22 04:45 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 2006-02-20 10:20:56 UTC
Hi,

when running Cygwin on NT, files are stat(2)ed using
NtQueryInformationFile(FileAllInformation).  When stat'ing directories
on Samba shares, I found that the StandardInformation.NumberOfLinks
member of the FILE_ALL_INFORMATION structure returned by
NtQueryInformationFile most of the time contains the value 1, regardless
of the actual link count of the directory.  If that would be stable
behaviour, I wouldn't mind, since that would be consistent with the
link count returned for directories on ordinary Windows file systems,
but it isn't stable.  I have a situation like this:

linux$ ls -l
drwxr-xr-x  11 corinna users     4096 Jan 28  2005 foo
drwxr-xr-x  40 corinna users     4096 Feb 18 10:20 bar

cygwin$ ls -l
drwxr-xr-x  10 corinna users     4096 Jan 28  2005 foo
drwxr-xr-x   1 corinna users     4096 Feb 18 10:20 bar

So, for the foo directory the link count is always 10, though 11
would be correct, while the bar directory most of the time
returns with a link count of 1, though 40 would be correct.
What's especially weird is that sometimes (1 time out of
10 or so), the link count returned for the "bar" directory
is 39.  I inspected the smbd source code but I couldn't
find any line which would explain this weird behaviour.


Thanks for any feedback,
Corinna
Comment 1 Jeremy Allison 2006-02-21 19:45:56 UTC
There is explicit code to not return accurate link counts for directories, as this is what NTFS seems to do. See here in smbd/trans2.c :

        nlink = sbuf.st_nlink;

        if ((nlink > 0) && S_ISDIR(sbuf.st_mode)) {
                /* NTFS does not seem to count ".." */
                nlink -= 1;
        }

Can you test against a remote NTFS drive please and let me know if you get
accurrate link counts before I remove this code.

Jeremy.
Comment 2 Corinna Vinschen 2006-02-22 04:42:12 UTC
I tested this again and my results are these:

- The unreliability of the link count returned for directories on a Samba
  share (sometimes 1, sometimes some n > 1) is apparently a local Windows
  weirdness.  I attached a small test application which must be built (with
  Cygwin or MingW gcc) using

    gcc -o zwqueryinformationfile zwqueryinformationfile.c -lntdll

  The information returned by ZwQueryInformationFile contains a sub-structure
  "StandardInformation", which has a link count member:

    ULONG NumberOfLinks;

  The weirdness is this:  If ZwOpenFile is called without the FILE_READ_DATA
  access flag, then the above NumberOfLinks value is 1 for most directories
  on a Samba share.  For some reason there are a few directories for which
  the link count is set to the value returned by Samba.

  If ZwOpenFile is called *with* the FILE_READ_DATA access flag, then the
  link count set in NumberOfLinks is the value returned by Samba for *all*
  directories.  Go figure!

  For plain files the link count is always correct and does not depend
  on the usage of FILE_READ_DATA, which is more what I would expect.
  Here (READ_CONTROL | FILE_READ_ATTRIBUTES) is sufficient.  Oh well...

- All native Windows file systems, regardless of being remote or local,
  return a link count of 1 for directories.  This is independent of the
  usage of FILE_READ_DATA in ZwOpenFile.


Corinna
Comment 3 Corinna Vinschen 2006-02-22 04:45:44 UTC
Created attachment 1750 [details]
Windows testcase for hardlink count on Samba shares

To test the working against the non-working version,
just replace WORKING_LINK_COUNT_ACCESS in the call
to ZwOpenFile with BROKEN_LINK_COUNT_ACCESS.

The arguments to the testcase are Windows filenames,
for instance, //server/share/foo.


Corinna
Comment 4 Corinna Vinschen 2006-02-22 05:03:05 UTC
Btw.,

I would appreciate if the link count returned by Samba is either
always 1 or always the correct one (not decremented by 1).

The reason is that a wrong link count can confuse some applications.
I don't know off the top of my head if find(1) still has this
problem, but I know for sure that older find versions took a link
count of 2 as a sure sign that the directory has no subdirectories,
which in turn resulted in some unfortunate optimization.  So, if you
have a directory with one subdir, a link count of 3 would be correct.
However, due to the decrementing of one, Samba would return 2 as the
link count and (older?) find would get confused.  OTOH, A directory
link count of 1 always worked fine, also for older find versions.

My personal preference would be to return the correct link count,
but I could also live with always returning 1 since that's what I'm
used to from other file systems anyway ;-)


Thanks,
Corinna
Comment 5 Corinna Vinschen 2006-08-20 06:12:08 UTC
Was there any resolution to this problem?

Curious,
Corinna
Comment 6 Arne de Bruijn 2007-01-16 05:42:29 UTC
I recently upgraded from samba 3.0.9 to 3.0.22 and hit this problem, the directory link count is one too low while using cifs on linux with unix extensions disabled, which confuses find(1).

I verified the link count as returned by cifs against a XP NTFS share and the link count was always 1 for directories and 2 for a (once) hardlinked file (fsutil hardlink create).

I think it would be better to restore the old behaviour (return unmodified link count) or return link count == 1 for directories (at least that would save me from manually patching samba :-)
Comment 7 Corinna Vinschen 2008-01-17 08:08:02 UTC
ping?
Comment 8 Jeremy Allison 2008-01-18 19:45:24 UTC
Fixed for 3.2 and 3.0.28a.
Thanks
Jeremy.