Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b688741c authored by NeilBrown's avatar NeilBrown Committed by Anna Schumaker
Browse files

NFS: revalidate "." etc correctly on "open".



For correct close-to-open semantics, NFS must validate
the change attribute of a directory (or file) on open.

Since commit ecf3d1f1 ("vfs: kill FS_REVAL_DOT by adding a
d_weak_revalidate dentry op"), open() of "." or a path ending ".." is
not revalidated reliably (except when that direct is a mount point).

Prior to that commit, "." was revalidated using nfs_lookup_revalidate()
which checks the LOOKUP_OPEN flag and forces revalidation if the flag is
set.
Since that commit, nfs_weak_revalidate() is used for NFSv3 (which
ignores the flags) and nothing is used for NFSv4.

This is fixed by using nfs_lookup_verify_inode() in
nfs_weak_revalidate().  This does the revalidation exactly when needed.
Also, add a definition of .d_weak_revalidate for NFSv4.

The incorrect behavior is easily demonstrated by running "echo *" in
some non-mountpoint NFS directory while watching network traffic.
Without this patch, "echo *" sometimes doesn't produce any traffic.
With the patch it always does.

Fixes: ecf3d1f1 ("vfs: kill FS_REVAL_DOT by adding a d_weak_revalidate dentry op")
cc: stable@vger.kernel.org (3.9+)
Signed-off-by: default avatarNeilBrown <neilb@suse.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 1750d929
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -1241,8 +1241,7 @@ static int nfs_weak_revalidate(struct dentry *dentry, unsigned int flags)
		return 0;
		return 0;
	}
	}


	if (nfs_mapping_need_revalidate_inode(inode))
	error = nfs_lookup_verify_inode(inode, flags);
		error = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
	dfprintk(LOOKUPCACHE, "NFS: %s: inode %lu is %s\n",
	dfprintk(LOOKUPCACHE, "NFS: %s: inode %lu is %s\n",
			__func__, inode->i_ino, error ? "invalid" : "valid");
			__func__, inode->i_ino, error ? "invalid" : "valid");
	return !error;
	return !error;
@@ -1393,6 +1392,7 @@ static int nfs4_lookup_revalidate(struct dentry *, unsigned int);


const struct dentry_operations nfs4_dentry_operations = {
const struct dentry_operations nfs4_dentry_operations = {
	.d_revalidate	= nfs4_lookup_revalidate,
	.d_revalidate	= nfs4_lookup_revalidate,
	.d_weak_revalidate	= nfs_weak_revalidate,
	.d_delete	= nfs_dentry_delete,
	.d_delete	= nfs_dentry_delete,
	.d_iput		= nfs_dentry_iput,
	.d_iput		= nfs_dentry_iput,
	.d_automount	= nfs_d_automount,
	.d_automount	= nfs_d_automount,