Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 1631

kernel-2.6.18-128.1.10.el5.src.rpm

From: Steve Dickson <SteveD@redhat.com>
Date: Tue, 1 Apr 2008 15:11:24 -0400
Subject: [nfs] fix the fsid revalidation in nfs_update_inode
Message-id: 47F288DC.3000404@RedHat.com
O-Subject: [RHEL 5.2] [BZ431166] NFS: 'No such file or directory' error from working Netapp NFS
Bugzilla: 431166

Here is a late breaking patch that stop the revalidation
of the client's notion of the filsystem ID (or FID).

As https://bugzilla.redhat.com/show_bug.cgi?id=431166#c38
explains:

When we detect that we've crossed a mountpoint on the remote server, we
must take care not to use that inode to revalidate the fsid on our
current superblock. To do so, we label the inode as a remote mountpoint,
and check for that in nfs_update_inode().

I was able to reproduce this problem with without a Netapp server
as https://bugzilla.redhat.com/show_bug.cgi?id=431166#c44 explains:

It seems I can reproduce this problem using V4 and a linux NFS server in
a rawhide kernel by exporting a "filesystem tree" of at least
three filesystem. Something similar to:

   export /fs1
   export /fs1/fs2
   export /fs1/fs2/fs3

Then do a v4 mount on a client
   mount -t nfs4 server:/fs1 /mnt/fs1

Now when the third filesystem is access from the client
   ls /mnt/fs1/fs2/fs3

the access fails with ESTALE because does the fids are not handled
correctly, which this patch does address.

The point of all this is, this looks like its a good patch
and we should try to move forward with it.

Please ACK.

steved.

From: Trond Myklebust <Trond.Myklebust@netapp.com>
Date: Thu, 6 Mar 2008 12:34:50 -0500
NFS: Fix the fsid revalidation in nfs_update_inode()

When we detect that we've crossed a mountpoint on the remote server, we
must take care not to use that inode to revalidate the fsid on our
current superblock. To do so, we label the inode as a remote mountpoint,
and check for that in nfs_update_inode().

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

Acked-by: Peter Staubach <staubach@redhat.com>
Acked-by: Jeff Layton <jlayton@redhat.com>

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 1e9ce09..53f96fa 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -286,6 +286,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
 				else
 					inode->i_op = &nfs_mountpoint_inode_operations;
 				inode->i_fop = NULL;
+				set_bit(NFS_INO_MOUNTPOINT, &nfsi->flags);
 			}
 		} else if (S_ISLNK(inode->i_mode))
 			inode->i_op = &nfs_symlink_inode_operations;
@@ -921,8 +922,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 
 	server = NFS_SERVER(inode);
 	/* Update the fsid? */
-	if (S_ISDIR(inode->i_mode)
-			&& !nfs_fsid_equal(&server->fsid, &fattr->fsid))
+	if (S_ISDIR(inode->i_mode) &&
+			!nfs_fsid_equal(&server->fsid, &fattr->fsid) &&
+			!test_bit(NFS_INO_MOUNTPOINT, &nfsi->flags))
 		server->fsid = fattr->fsid;
 
 	/*
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 004e5b5..623c099 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -220,6 +220,7 @@ struct nfs_inode {
 #define NFS_INO_STALE		(2)		/* possible stale inode */
 #define NFS_INO_ACL_LRU_SET	(3)		/* Inode is on the LRU list */
 #define NFS_INO_FSCACHE	(4)		/* inode can be cached by FS-Cache */
+#define NFS_INO_MOUNTPOINT	(5)		/* inode is remote mountpoint */
 
 static inline struct nfs_inode *NFS_I(struct inode *inode)
 {