Messages in this thread Patch in this message |  | | Date | Wed, 10 Jul 1996 18:44:59 +0200 | From | Kees Bakker <> | Subject | NFS still has caching problem |
| |
Hi Linus,
Today I have booted my system with linux-2.0.4, and saw it still has the following problem with directory caching. Let's first briefly describe the test environment. NFS server, called napoli, is an Alpha, and runs OSF1 v2.0 NFS client 1, called lahti, runs linux-2.0.4 ('out of the box') NFS client 2, called pori, runs linux-1.3.83 (with my nfs/dir.c patch)
The test is as follows: - on one client, write a file - then do a 'rsh' to another client and 'cat' the file - again, on the first client, write the same file, different contents - again, do a 'rsh' to another client and 'cat' the file You will see that the Linux clients keep showing the old contents if the size of the file remains the same. If the new size is different, then the Linux client shows the new contents.
To sync the NFS server, I have written a small C program that uses fsync(). But that does not change the behavior.
Here is a logging of the test.
/usr/sec/kees > rlogin turku No mail. /usr/sec/kees > RNODE=pori ./t4-nfs going to do: rsh pori cd `pwd`\; cat t3-nfs.txt 1 --Hello, world going to do: rsh pori cd `pwd`\; cat t3-nfs.txt 2 --Hallo, 12345 going to do: rsh pori cd `pwd`\; cat t3-nfs.txt 3 --Hello, wwwww 3 going to do: rsh pori cd `pwd`\; cat t3-nfs.txt 4 --Hallo, world 4 going to do: rsh pori cd `pwd`\; cat t3-nfs.txt 5 --Hallo, world 5 going to do: rsh pori cd `pwd`\; cat t3-nfs.txt 6 --Hallo, world 6 going to do: rsh pori cd `pwd`\; cat t3-nfs.txt 7 --Hallo, world 7 going to do: rsh pori cd `pwd`\; cat t3-nfs.txt 8 --Hallo, world 8
/usr/sec/kees > RNODE=lahti ./t4-nfs going to do: rsh lahti cd `pwd`\; cat t3-nfs.txt 1 --Hello, world going to do: rsh lahti cd `pwd`\; cat t3-nfs.txt 1 --Hello, world going to do: rsh lahti cd `pwd`\; cat t3-nfs.txt 3 --Hello, wwwww 3 going to do: rsh lahti cd `pwd`\; cat t3-nfs.txt 3 --Hello, wwwww 3 going to do: rsh lahti cd `pwd`\; cat t3-nfs.txt 3 --Hello, wwwww 3 going to do: rsh lahti cd `pwd`\; cat t3-nfs.txt 3 --Hello, wwwww 3 going to do: rsh lahti cd `pwd`\; cat t3-nfs.txt 3 --Hello, wwwww 3 going to do: rsh lahti cd `pwd`\; cat t3-nfs.txt 3 --Hello, wwwww 3
The first session is correct, the Linux system pori has my patch. The second session is wrong, the Linux system lahti, does not have the patch.
My patch: If you have a look at fs/nfs/dir.c you see the following piece of code:
was_empty = (inode->i_mode == 0); inode->i_mode = fattr->mode; inode->i_nlink = fattr->nlink; inode->i_uid = fattr->uid; inode->i_gid = fattr->gid;
/* Size changed from outside: invalidate caches on next read */ if (inode->i_size != fattr->size) NFS_CACHEINV(inode); inode->i_size = fattr->size; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) inode->i_rdev = to_kdev_t(fattr->rdev); else inode->i_rdev = 0; inode->i_blocks = fattr->blocks; inode->i_atime = fattr->atime.seconds; inode->i_mtime = fattr->mtime.seconds; inode->i_ctime = fattr->ctime.seconds;
Notice that this part only checks for changed file sizes, not for anything else. Perhaps you are assuming that modification times are check somewhere else, but it certainly does not affect this part. I tried a little patch, which seems to work, but I don't know if this is the right place to make this modification. This is what I tried:
--- linux/fs/nfs/dir.c.orig Wed Mar 13 12:53:09 1996 +++ linux/fs/nfs/dir.c Fri Mar 22 09:06:10 1996 @@ -613,14 +613,17 @@ return; } was_empty = (inode->i_mode == 0); - inode->i_mode = fattr->mode; inode->i_nlink = fattr->nlink; inode->i_uid = fattr->uid; inode->i_gid = fattr->gid; - /* Size changed from outside: invalidate caches on next read */ - if (inode->i_size != fattr->size) + /* Size and/or time changed from outside: invalidate caches on next read */ + if (inode->i_size != fattr->size || + inode->i_mtime != fattr->mtime.seconds || + inode->i_mode != fattr->mode + ) NFS_CACHEINV(inode); + inode->i_mode = fattr->mode; inode->i_size = fattr->size; inode->i_blksize = fattr->blocksize; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) Now it will also look at i_mtime and i_mode. Question is, should that be checked here?
I would happy to send you the C file, and the shell script, if you want to try it out. -- ============================================================ Kees Bakker phone : +31 33 4558584 Tasking Software BV fax : +31 33 4550033 Plotterweg 31 kees@tasking.nl Amersfoort, The Netherlands http://www.tasking.nl ============================================================ Speak the word, the word is all of us - Queensryche
|  |