linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] nfs: nfs_fileid_valid() is wrong on NFSv3 and incomplete on NFSv4
@ 2018-03-01  0:25 Eric Rannaud
  2018-03-14 19:36 ` Anna Schumaker
  0 siblings, 1 reply; 4+ messages in thread
From: Eric Rannaud @ 2018-03-01  0:25 UTC (permalink / raw)
  To: linux-nfs; +Cc: Eric Rannaud, Trond Myklebust, Anna Schumaker, Jessica Peters

On NFSv3, in normal circumstances, NFS_ATTR_FATTR_MOUNTED_ON_FILEID is
not set on fattr->valid. It is only set in nfs3_decode_dirent() if
entry->fattr->fileid != entry->ino, which typically only happens for
mountpoints. (See 1ae04b252351 NFSv3: Use the readdir fileid as the
mounted-on-fileid.)

nfs_fileid_valid() returns 'ret1 || ret2', initializing both ret1 and
ret2 to true, but sets them only conditionally. Therefore, in normal
circumstances, nfs_fileid_valid() wrongly returns 'false || true' when
the fileid has changed.

There is another bug in this function for NFSv4: a server may return a
fattr with NFS_ATTR_FATTR_FILEID|NFS_ATTR_FATTR_MOUNTED_ON_FILEID.
nfs_fileid_valid() will fail to detect a change in fileid in the case
where the fattr->fileid happens to match, by chance, the stored
nfsi->fileid (copied from a previous fattr->mounted_on_fileid).

If this is a mountpoint, the current fattr->fileid and the old
fattr->mounted_on_fileid come from different filesystems and may well
happen to be identical.

The condition should be written as an if / else if:

	if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
	else if (fattr->valid & NFS_ATTR_FATTR_FILEID)

as is done elsewhere in NFSv4 code.
---
 fs/nfs/inode.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 7d893543cf3b..e1ad5ec75795 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1717,13 +1717,11 @@ EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc);
 static inline bool nfs_fileid_valid(struct nfs_inode *nfsi,
 				    struct nfs_fattr *fattr)
 {
-	bool ret1 = true, ret2 = true;
-
-	if (fattr->valid & NFS_ATTR_FATTR_FILEID)
-		ret1 = (nfsi->fileid == fattr->fileid);
 	if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
-		ret2 = (nfsi->fileid == fattr->mounted_on_fileid);
-	return ret1 || ret2;
+		return nfsi->fileid == fattr->mounted_on_fileid;
+	else if (fattr->valid & NFS_ATTR_FATTR_FILEID)
+		return nfsi->fileid == fattr->fileid;
+	return true;
 }
 
 /*
-- 
2.16.2


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

end of thread, other threads:[~2018-03-19 19:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-01  0:25 [PATCH] nfs: nfs_fileid_valid() is wrong on NFSv3 and incomplete on NFSv4 Eric Rannaud
2018-03-14 19:36 ` Anna Schumaker
2018-03-17  0:57   ` Eric Rannaud
2018-03-19 19:52     ` Anna Schumaker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).