Commit eea41330 authored by Trond Myklebust's avatar Trond Myklebust

NFS: Default change_attr_type to NFS4_CHANGE_TYPE_IS_UNDEFINED

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: 7b24dacf ("NFS: Another inode revalidation improvement")
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Tested-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent a1e7f30a
...@@ -1777,8 +1777,10 @@ static int nfs_inode_finish_partial_attr_update(const struct nfs_fattr *fattr, ...@@ -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_BLOCKS | NFS_INO_INVALID_OTHER |
NFS_INO_INVALID_NLINK; NFS_INO_INVALID_NLINK;
unsigned long cache_validity = NFS_I(inode)->cache_validity; 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 && (cache_validity & check_valid) != 0 &&
(fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && (fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
nfs_inode_attrs_cmp_monotonic(fattr, inode) == 0) nfs_inode_attrs_cmp_monotonic(fattr, inode) == 0)
......
...@@ -2227,7 +2227,7 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr, ...@@ -2227,7 +2227,7 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr,
/* ignore properties */ /* ignore properties */
result->lease_time = 0; 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; return 0;
} }
......
...@@ -91,7 +91,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, ...@@ -91,7 +91,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
info->dtpref = fsinfo.tsize; info->dtpref = fsinfo.tsize;
info->maxfilesize = 0x7FFFFFFF; info->maxfilesize = 0x7FFFFFFF;
info->lease_time = 0; 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; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment