aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-05-25 01:40:46 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-09 09:34:04 -0400
commit9d1e9232223a7f065be7f956a7b749a4cbbbe16d (patch)
treecf535655bda226c5d306fffdb40bc22fbeb5aedb /fs/nfs
parent1de3fc12ea085690547a54b6efa01c7348f1cebd (diff)
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: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/inode.c22
1 files changed, 9 insertions, 13 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index d0b991a9232..e870e4aae71 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1414,9 +1414,8 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
1414 /* Do atomic weak cache consistency updates */ 1414 /* Do atomic weak cache consistency updates */
1415 nfs_wcc_update_inode(inode, fattr); 1415 nfs_wcc_update_inode(inode, fattr);
1416 1416
1417 if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0) { 1417 if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
1418 if (nfsi->change_attr == fattr->change_attr) 1418 nfsi->change_attr != fattr->change_attr) {
1419 goto out;
1420 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1419 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
1421 if (!data_unstable) 1420 if (!data_unstable)
1422 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; 1421 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 if (inode->i_nlink != fattr->nlink) 1443 if (inode->i_nlink != fattr->nlink)
1445 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1444 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
1446 1445
1447out:
1448 if (!timespec_equal(&inode->i_atime, &fattr->atime)) 1446 if (!timespec_equal(&inode->i_atime, &fattr->atime))
1449 nfsi->cache_validity |= NFS_INO_INVALID_ATIME; 1447 nfsi->cache_validity |= NFS_INO_INVALID_ATIME;
1450 1448
@@ -1612,15 +1610,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1612 inode->i_blksize = fattr->du.nfs2.blocksize; 1610 inode->i_blksize = fattr->du.nfs2.blocksize;
1613 } 1611 }
1614 1612
1615 if ((fattr->valid & NFS_ATTR_FATTR_V4)) { 1613 if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
1616 if (nfsi->change_attr != fattr->change_attr) { 1614 nfsi->change_attr != fattr->change_attr) {
1617 dprintk("NFS: change_attr change on server for file %s/%ld\n", 1615 dprintk("NFS: change_attr change on server for file %s/%ld\n",
1618 inode->i_sb->s_id, inode->i_ino); 1616 inode->i_sb->s_id, inode->i_ino);
1619 nfsi->change_attr = fattr->change_attr; 1617 nfsi->change_attr = fattr->change_attr;
1620 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1618 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1621 nfsi->cache_change_attribute = jiffies; 1619 nfsi->cache_change_attribute = jiffies;
1622 } else
1623 invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA);
1624 } 1620 }
1625 1621
1626 /* Update attrtimeo value if we're out of the unstable period */ 1622 /* Update attrtimeo value if we're out of the unstable period */