From: Timo Sirainen <tss@iki.fi>
To: linux-nfs@vger.kernel.org
Subject: inode caching
Date: Mon, 26 May 2008 23:58:19 +0300 [thread overview]
Message-ID: <1211835499.3904.231.camel@hurina> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 1315 bytes --]
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
[-- Attachment #1.2: t.c --]
[-- Type: text/x-csrc, Size: 926 bytes --]
#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 #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
next reply other threads:[~2008-05-26 21:25 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-26 20:58 Timo Sirainen [this message]
2008-05-27 12:48 ` inode caching Peter Staubach
2008-05-27 15:40 ` Timo Sirainen
2008-05-27 18:09 ` Peter Staubach
2008-05-27 19:13 ` Timo Sirainen
2008-05-28 5:38 ` Benny Halevy
2008-05-28 13:59 ` J. Bruce Fields
2008-05-28 15:20 ` Timo Sirainen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1211835499.3904.231.camel@hurina \
--to=tss@iki.fi \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.