NFS server: Linux 2.6.25 NFS client: Linux debian 2.6.25-2 (or 2.6.23.1) If I do: NFS client: fd1 = creat("foo"); write(fd1, "xx", 2); fsync(fd1); NFS server: unlink("foo"); creat("foo"); NFS client: fd2 = open("foo"); fstat(fd1, &st1); fstat(fd2, &st2); fstat(fd1, &st3); The result is usually that the fstat(fd1) fails with ESTALE. But sometimes the result is st1.st_ino == st2.st_ino == st3.st_ino and st1.st_size == 2 but st2.st_size == 0. So I see two different files using the same inode number. I'd really want to avoid seeing that condition. So what I'd want to know is: a) Why does this happen only sometimes? I can't really figure out from the code what invalidates the fd1 inode. Apparently the second open() somehow, but since it uses the new "foo" file with a different struct inode, where does the old struct inode get invalidated? b) Can this be fixed? Or is it just luck that it works as well as it does now? Attached a test program. Usage: NFS client: Mount with actimeo=2 NFS client: ./t (Run the next two commands within 2 seconds) NFS server: rm -f foo;touch foo NFS client: hit enter Once in a while the result will be: 1a: ino=15646940 size=2 1b: ino=15646940 size=2 1c: ino=15646940 size=2 2: ino=15646940 size=0 1d: ino=15646940 size=2
#include <errno.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <sys/stat.h> int main(void) { struct stat st; int fd, fd2; char buf[100]; fd = open("foo", O_RDWR | O_CREAT, 0666); write(fd, "xx", 2); fsync(fd); if (fstat(fd, &st) < 0) perror("fstat()"); printf("1a: ino=%ld size=%ld\n", (long)st.st_ino, st.st_size); fgets(buf, sizeof(buf), stdin); if (fstat(fd, &st) < 0) perror("fstat()"); else printf("1b: ino=%ld size=%ld\n", (long)st.st_ino, st.st_size); fd2 = open("foo", O_RDWR); if (fstat(fd, &st) < 0) perror("fstat()"); else printf("1c: ino=%ld size=%ld\n", (long)st.st_ino, st.st_size); if (fstat(fd2, &st) < 0) perror("fstat()"); else printf("2: ino=%ld size=%ld\n", (long)st.st_ino, st.st_size); if (fstat(fd, &st) < 0) perror("fstat()"); else printf("1d: ino=%ld size=%ld\n", (long)st.st_ino, st.st_size); return 0; }
Attachment:
signature.asc
Description: This is a digitally signed message part