Skip to content

Commit

Permalink
NFS: Default change_attr_type to NFS4_CHANGE_TYPE_IS_UNDEFINED
Browse files Browse the repository at this point in the history
[ Upstream commit eea4133 ]

Both NFSv3 and NFSv2 generate their change attribute from the ctime
value that was supplied by the server. However the problem is that there
are plenty of servers out there with ctime resolutions of 1ms or worse.
In a modern performance system, this is insufficient when trying to
decide which is the most recent set of attributes when, for instance, a
READ or GETATTR call races with a WRITE or SETATTR.

For this reason, let's revert to labelling the NFSv2/v3 change
attributes as NFS4_CHANGE_TYPE_IS_UNDEFINED. This will ensure we protect
against such races.

Fixes: 7b24dac ("NFS: Another inode revalidation improvement")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Tested-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Trond Myklebust authored and gregkh committed Nov 17, 2021
1 parent 6033546 commit cbe0ef0
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 3 deletions.
4 changes: 3 additions & 1 deletion fs/nfs/inode.c
Expand Up @@ -1777,8 +1777,10 @@ static int nfs_inode_finish_partial_attr_update(const struct nfs_fattr *fattr,
NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_OTHER |
NFS_INO_INVALID_NLINK;
unsigned long cache_validity = NFS_I(inode)->cache_validity;
enum nfs4_change_attr_type ctype = NFS_SERVER(inode)->change_attr_type;

if (!(cache_validity & NFS_INO_INVALID_CHANGE) &&
if (ctype != NFS4_CHANGE_TYPE_IS_UNDEFINED &&
!(cache_validity & NFS_INO_INVALID_CHANGE) &&
(cache_validity & check_valid) != 0 &&
(fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
nfs_inode_attrs_cmp_monotonic(fattr, inode) == 0)
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/nfs3xdr.c
Expand Up @@ -2227,7 +2227,7 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr,

/* ignore properties */
result->lease_time = 0;
result->change_attr_type = NFS4_CHANGE_TYPE_IS_TIME_METADATA;
result->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/proc.c
Expand Up @@ -91,7 +91,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
info->dtpref = fsinfo.tsize;
info->maxfilesize = 0x7FFFFFFF;
info->lease_time = 0;
info->change_attr_type = NFS4_CHANGE_TYPE_IS_TIME_METADATA;
info->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;
return 0;
}

Expand Down

0 comments on commit cbe0ef0

Please sign in to comment.