The connectathon nfsidem test fails on CIFS when a filesystem is mounted w/o unix extensions. The issue seems to be that we are able to create a hardlink for a file, but the resulting dentry seems to be attached to a different inode (with different permissions, different st_ino, etc). For instance: [root@dhcp231-179 dantu]# touch foo [root@dhcp231-179 dantu]# ln foo bar [root@dhcp231-179 dantu]# stat foo bar File: `foo' Size: 0 Blocks: 8 IO Block: 16384 regular empty file Device: 17h/23d Inode: 52529 Links: 2 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2007-05-10 11:22:20.000000000 -0400 Modify: 2007-05-10 11:22:20.000000000 -0400 Change: 2007-05-10 11:22:20.000000000 -0400 File: `bar' Size: 0 Blocks: 8 IO Block: 16384 regular empty file Device: 17h/23d Inode: 52551 Links: 2 Access: (3767/-rwxrwSrwt) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2007-05-10 11:22:20.000000000 -0400 Modify: 2007-05-10 11:22:20.000000000 -0400 Change: 2007-05-10 11:22:20.000000000 -0400
Some idle speculation... This may not be fixable. NT_RENAME seems to allow for the creation of hardlinks, but the issue comes in identifying them afterward. How does one ID a hardlink on a standard NT machine? Or are they even hardlinks in the way we conceptualize them? The protocol itself probably doesn't allow us and means to ID them as well. I'll still have a look, but this may be a CANTFIX sort of issue...
This page talks about hardlinks on NTFS and how to identify them. It looks like there *is* something akin to an inode number in NTFS that's stored in 2 fields: nFileIndexHigh nFileIndexLow The page that talks about it is here: http://msdn2.microsoft.com/en-us/library/ms810604.aspx ...I suppose the issue, however is that this info is not passed over the wire in the SMB protocol. Still looking to confirm this, but again I doubt this is fixable.
Actually, the CIFS spec seems to indicate that this may be possible to fix, at least in some cases: SMB_QUERY_FILE_ALL_INFO returns 2 fields that seem to correspond to an inode: LARGE_INTEGER IndexNumber; LARGE_INTEGER IndexNumber1; The spec just says that they are "A file system unique identifier" which sounds like an inode number of sorts. The big questions are: A) do samba and windows fill out this field? B) can we squish this down to a 32-bit value (LARGE_INTEGERS are 64 bits each, so we're dealing with 128-bits worth of data)? I'll look over some captures to see if I can tell what's up...
Hmm, actually, from the code comments: /* Is an i_ino of zero legal? Can we use that to check if the server supports returning inode numbers? Are there other sanity checks we can use to ensure that the server is really filling in that field? */ /* We can not use the IndexNumber field by default from Windows or Samba (in ALL_INFO buf) but we can request it explicitly. It may not be unique presumably if the server has multiple devices mounted under one share */ /* There may be higher info levels that work but are there Windows server or network appliances for which IndexNumber field is not guaranteed unique? */ Inode of 0 is a bit of an odd duck. My take would be to consider that to mean that the server isn't returning inode numbers. It seems like if the server *is* returning these values as non-zero we ought to try to use them to generate inode numbers.
...it also seems like we could fix up samba to handle the "multiple devices under one share" issue as well. It could just encode the device ID in the value returned (since we have 128 bits to play with, it seems reasonable that we could include it). Windows, however, is a different matter...
Reopening bug, closed by accident
George Colley from Apple replied to my query on the cifs-protocol mailing list: The SNIA Spec is wrong on this call and several others. I am working on updating my web version of Paul Leach's Draft. Once I get it in order I plan on posting it publicly . I plan is to make this a living document that can be changed by the experts in the field (who every they are). 4.2.14.8 SMB_QUERY_FILE_ALL_INFO Data Block Encoding =============================== Description ==================================== LARGE_INTEGER CreationTime; Time when file was created LARGE_INTEGER LastAccessTime; Time of last file access LARGE_INTEGER LastWriteTime; Time of last write to the file LARGE_INTEGER ChangeTime Time when file was last changed ULONG Attributes; File Attributes LARGE_INTEGER AllocationSize Allocated size of the file in number of bytes LARGE_INTEGER EndofFile; Offset to the first free byte in the file ULONG NumberOfLinks Number of hard links to the file BOOLEAN DeletePending Indicates whether the file is marked for deletion BOOLEAN Directory Indicates whether the file is a directory USHORT Unknown Could be a padd value? ULONG EASize Size of the file's extended attributes in bytes ULONG FileNameLength Length of the file name in number of bytes STRING FileName Name of the file ...so the SNIA doc is wrong and I don't think there's anything we can do to get actual real inode numbers out. So this looks like it's a CANTFIX after all (unless we can use a different query type here).