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
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.
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
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
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
Was there any resolution to this problem? Curious, Corinna
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 :-)
ping?
Fixed for 3.2 and 3.0.28a. Thanks Jeremy.