> If I didn't make it clear /home/david directory is the stale
> NFS filehandle and server:/home is mounted on /home so it isn't
> the root directory inode here that is having the problem.
Ah. Sorry... Neil's argumentation made me think it might be the root
inode that was stale. Indeed from the code that is currently a
pathology.
Hmm: it looks like the dentry revalidation code is in any case not
complete. Basically it doesn't check if the NFS_INO_STALE flag is set
when deciding whether or not a cached dentry is valid.
OK. We need the patch I sent last night plus a 1-liner in
nfs_inode_is_stale(). That should cover both pathologies. It'll
probably clean up the other cases in which people have been reporting
-ESTALE errors.
Cheers,
Trond
--- linux-2.4.2/fs/nfs/inode.c.orig Wed Feb 14 01:14:28 2001
+++ linux-2.4.2/fs/nfs/inode.c Thu Mar 1 10:00:15 2001
@@ -632,7 +632,7 @@
if ((fattr->mode & S_IFMT) != (inode->i_mode & S_IFMT))
return 1;
- if (is_bad_inode(inode))
+ if (is_bad_inode(inode) || NFS_STALE(inode))
return 1;
/* Has the filehandle changed? If so is the old one stale? */
@@ -819,24 +819,22 @@
int
__nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
{
- int status = 0;
+ int status = -ESTALE;
struct nfs_fattr fattr;
dfprintk(PAGECACHE, "NFS: revalidating (%x/%Ld)\n",
inode->i_dev, (long long)NFS_FILEID(inode));
lock_kernel();
- if (!inode || is_bad_inode(inode) || NFS_STALE(inode)) {
- unlock_kernel();
- return -ESTALE;
- }
+ if (!inode || is_bad_inode(inode))
+ goto out_nowait;
+ if (NFS_STALE(inode) && inode != inode->i_sb->s_root->d_inode)
+ goto out_nowait;
while (NFS_REVALIDATING(inode)) {
status = nfs_wait_on_inode(inode, NFS_INO_REVALIDATING);
- if (status < 0) {
- unlock_kernel();
- return status;
- }
+ if (status < 0)
+ goto out_nowait;
if (time_before(jiffies,NFS_READTIME(inode)+NFS_ATTRTIMEO(inode))) {
status = NFS_STALE(inode) ? -ESTALE : 0;
goto out_nowait;
@@ -850,7 +848,8 @@
inode->i_dev, (long long)NFS_FILEID(inode), status);
if (status == -ESTALE) {
NFS_FLAGS(inode) |= NFS_INO_STALE;
- remove_inode_hash(inode);
+ if (inode != inode->i_sb->s_root->d_inode)
+ remove_inode_hash(inode);
}
goto out;
}
@@ -863,6 +862,8 @@
}
dfprintk(PAGECACHE, "NFS: (%x/%Ld) revalidation complete\n",
inode->i_dev, (long long)NFS_FILEID(inode));
+
+ NFS_FLAGS(inode) &= ~NFS_INO_STALE;
out:
NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING;
wake_up(&inode->i_wait);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/