Hello, This bug could be the same as bug#2748, but I am logging it anyway in case it is a different issue, or that it may add more information. Client: Debian 2.6.11 cifs-1.34 Server: Debian 2.4.27-2 3.0.10-1 STEPS TO REPRODUCE: In a cifs mount, execute the following code (see below for complete listing): open ("file.LCK", O_RDWR | O_CREAT | O_EXCL , 0); link ("file.LCK", "file.LNK"); stat ("file.LCK", &statbuf); RESULT: statbuf.st_nlink == 1 EXPECTED: statbuf.st_nlink == 2 Note 1: This happens even with the serverino option turned on. Note 2: I also noticed that executing a directory listing between the open, link, and stat calls, solves the problem. In other words, the following code works fine: open ("file.LCK", O_RDWR | O_CREAT | O_EXCL , 0); system("ls -la"); link ("file.LCK", "file.LNK"); system("ls -la"); stat ("file.LCK", &statbuf); RESULT: statbuf.st_nlink == 2 Thanks. #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <unistd.h> int main(void) { struct stat statbuf; int rc; int fd; fd = open ("file.LCK", O_RDWR | O_CREAT | O_EXCL , 0); if (fd < 0) { printf ("Error: %d\n", errno); return 1; } rc = link ("file.LCK", "file.LNK"); if (rc) { printf ("Error: %d\n", errno); return 1; } rc = stat ("file.LCK", &statbuf); if (rc) { printf ("Error: %d\n", errno); return 1; } if (statbuf.st_nlink != 2) { printf ("Opps...\n"); } printf("statbuf.st_nlink: %d\n", statbuf.st_nlink); close (fd); return 0; }
*** Bug 2748 has been marked as a duplicate of this bug. ***
Hello Steve, you closed bug 2748, but I found something wrong related to the inode number in between. I think it's related to this bug, however, so I won't reopen 2748: (kernel 2.6.11, cifs 1.34a, serverino, W2K3 server) martin@debian:/mnt/wintmp/0$ echo hello > link0 martin@debian:/mnt/wintmp/0$ ls -lin total 1 1263639 -rw-r--r-- 1 0 0 6 2005-07-17 23:25 link0 martin@debian:/mnt/wintmp/0$ cd .. martin@debian:/mnt/wintmp$ ln 0/link0 1/link1 martin@debian:/mnt/wintmp$ find . -size 6c -exec ls -lin {} \; 1263639 -rw-r--r-- 1 0 0 6 2005-07-17 23:25 ./0/link0 81585 -rw-r--r-- 1 0 0 6 2005-07-17 23:25 ./1/link1 Here, 81585 is the correct inode number (the same as reported by interix), but 1263639 seems to be a bogus one. I further observed that, if inode number is correct, then the link count is always 1. Sometimes the link count happens to be correct even if greater than 1, but then I always saw a wrong inode number. Or as above, both values are wrong. Martin
turned out to be pretty obvious - when the file is open on the client and cached (oplock) we were not going back to the server to get the updated link count, so we need to make sure it is updated locally for BOTH source and target of the link. Am checking now if that is possible.
Created attachment 2221 [details] patch to fix problem (patch against 2.6.19-rc6) let me know if this does not fix it - but it seems straightforward
Is there a big need to get this in before 2.6.19? Seems fairly minor (as the hardlink count is refreshed from server when oplock is lost or file closed - and only applies to nlink on a cached source file)
> Is there a big need to get this in before 2.6.19? No, this is a very minor issue indeed. I noticed this while opening a GNU Cash file on a cifs share. GNU Cash gives a warning saying that it could not lock the file. But other than that, I can open the file and work with it just fine.
Created attachment 2226 [details] script to test locking I veto against closing this bug! I tested the patch against 2.6.18 (cifs 1.45) without success. I think, however, that the underlying problem is a bigger one, and that this issue will disappear automatically, when the bigger one is resolved. (So I think it's too late for 2.6.19 anyway.) Test environment is still the same as before 1,5 years: Linux client, Win2K client, Win 2K3 server, serverino,directio mount option. I did on Linux 2.6.18 (cifs-1.45 + patch): $ cd /misc/wintmp $ find 0 1 -exec ls -lin {} \; 84011 -rw-r--r-- 1 0 0 6 Nov 18 15:26 0/link0 84011 -rw-r--r-- 1 0 0 6 Nov 18 15:26 1/link1 (already existing before starting Linux) $ ln 0/link0 0/link2 $ find 0 1 -exec ls -lin {} \; 84011 -rw-r--r-- 3 0 0 6 Nov 18 15:26 0/link0 84011 -rw-r--r-- 1 0 0 6 Nov 18 15:26 0/link2 84011 -rw-r--r-- 1 0 0 6 Nov 18 15:26 1/link1 $ touch 1/link1 $ find 0 1 -exec ls -lin {} \; 84011 -rw-r--r-- 3 0 0 6 Nov 18 15:38 0/link0 84011 -rw-r--r-- 1 0 0 6 Nov 18 15:26 0/link2 84011 -rw-r--r-- 1 0 0 6 Nov 18 15:38 1/link1 $ ln 1/link1 1/link3 $ find 0 1 -exec ls -lin {} \; 84011 -rw-r--r-- 4 0 0 6 Nov 18 15:38 0/link0 84011 -rw-r--r-- 1 0 0 6 Nov 18 15:26 0/link2 84011 -rw-r--r-- 4 0 0 6 Nov 18 15:38 1/link1 84011 -rw-r--r-- 1 0 0 6 Nov 18 15:38 1/link3 I then further did some locking tests, e.g. exclusively lock one link, and then try to exclusively lock a second link, see the attachment for the test script. $ locktest.pl /misc/wintmp/0/link0(a): successfully locked exclusive /misc/wintmp/0/link0(b): failed to lock exclusive /misc/wintmp/1/link1: successfully locked exclusive Unfortunately, the result is wrong. Testing the same on the Win2K client within interix (or on Linux and a nfs share) shows the expected: /misc/wintmp/0/link0(a): successfully locked exclusive /misc/wintmp/0/link0(b): failed to lock exclusive /misc/wintmp/1/link1: failed to lock exclusive Apparently, linux-cifs doesn't cache the file infos with a key like (server,device,inode) which it I think should for correctness, at least if serverino is given. Martin