Commit 9d1e9232 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Some NFSv4 servers have broken behaviour for the change attribute

The Linux NFSv4 server violates RFC3530 in that the change attribute is not
guaranteed to be updated for every change to the inode. Our optimisation
for checking whether or not the inode metadata has changed or not is broken
too. Grr....
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 1de3fc12
...@@ -1414,9 +1414,8 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat ...@@ -1414,9 +1414,8 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
/* Do atomic weak cache consistency updates */ /* Do atomic weak cache consistency updates */
nfs_wcc_update_inode(inode, fattr); nfs_wcc_update_inode(inode, fattr);
if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0) { if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
if (nfsi->change_attr == fattr->change_attr) nfsi->change_attr != fattr->change_attr) {
goto out;
nfsi->cache_validity |= NFS_INO_INVALID_ATTR; nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
if (!data_unstable) if (!data_unstable)
nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
...@@ -1444,7 +1443,6 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat ...@@ -1444,7 +1443,6 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
if (inode->i_nlink != fattr->nlink) if (inode->i_nlink != fattr->nlink)
nfsi->cache_validity |= NFS_INO_INVALID_ATTR; nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
out:
if (!timespec_equal(&inode->i_atime, &fattr->atime)) if (!timespec_equal(&inode->i_atime, &fattr->atime))
nfsi->cache_validity |= NFS_INO_INVALID_ATIME; nfsi->cache_validity |= NFS_INO_INVALID_ATIME;
...@@ -1612,15 +1610,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) ...@@ -1612,15 +1610,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
inode->i_blksize = fattr->du.nfs2.blocksize; inode->i_blksize = fattr->du.nfs2.blocksize;
} }
if ((fattr->valid & NFS_ATTR_FATTR_V4)) { if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
if (nfsi->change_attr != fattr->change_attr) { nfsi->change_attr != fattr->change_attr) {
dprintk("NFS: change_attr change on server for file %s/%ld\n", dprintk("NFS: change_attr change on server for file %s/%ld\n",
inode->i_sb->s_id, inode->i_ino); inode->i_sb->s_id, inode->i_ino);
nfsi->change_attr = fattr->change_attr; nfsi->change_attr = fattr->change_attr;
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
nfsi->cache_change_attribute = jiffies; nfsi->cache_change_attribute = jiffies;
} else
invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA);
} }
/* Update attrtimeo value if we're out of the unstable period */ /* Update attrtimeo value if we're out of the unstable period */
......
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