All of lore.kernel.org
 help / color / mirror / Atom feed
* inode caching
@ 2008-05-26 20:58 Timo Sirainen
  2008-05-27 12:48 ` Peter Staubach
  0 siblings, 1 reply; 8+ messages in thread
From: Timo Sirainen @ 2008-05-26 20:58 UTC (permalink / raw)
  To: linux-nfs


[-- 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 --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-05-28 15:21 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-26 20:58 inode caching Timo Sirainen
2008-05-27 12:48 ` 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

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.