aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:07 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:07 -0500
commitca62b9c3f7b8679ada4de94d2ab7098c6860c3d7 (patch)
treec4eb7adef74b2ccdf5b928f698d80f6cdcb6f708
parent755c1e20cd2ad56e5c567fa05769eb98a3eef72b (diff)
NFSv4: Don't invalidate cached attributes if change attribute is unchanged
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/inode.c44
1 files changed, 24 insertions, 20 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 5746dc841a6c..0e1ef97bcf54 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1299,34 +1299,35 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
1299 if ((fattr->valid & NFS_ATTR_FATTR) == 0) 1299 if ((fattr->valid & NFS_ATTR_FATTR) == 0)
1300 return 0; 1300 return 0;
1301 1301
1302 /* Has the inode gone and changed behind our back? */
1303 if (nfsi->fileid != fattr->fileid
1304 || (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
1305 return -EIO;
1306 }
1307
1302 /* Are we in the process of updating data on the server? */ 1308 /* Are we in the process of updating data on the server? */
1303 data_unstable = nfs_caches_unstable(inode); 1309 data_unstable = nfs_caches_unstable(inode);
1304 1310
1305 /* Do atomic weak cache consistency updates */ 1311 /* Do atomic weak cache consistency updates */
1306 nfs_wcc_update_inode(inode, fattr); 1312 nfs_wcc_update_inode(inode, fattr);
1307 1313
1308 if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 && 1314 if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0) {
1309 nfsi->change_attr != fattr->change_attr) { 1315 if (nfsi->change_attr == fattr->change_attr)
1316 goto out;
1310 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1317 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
1311 if (!data_unstable) 1318 if (!data_unstable)
1312 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; 1319 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
1313 } 1320 }
1314 1321
1315 /* Has the inode gone and changed behind our back? */
1316 if (nfsi->fileid != fattr->fileid
1317 || (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
1318 return -EIO;
1319 }
1320
1321 cur_size = i_size_read(inode);
1322 new_isize = nfs_size_to_loff_t(fattr->size);
1323
1324 /* Verify a few of the more important attributes */ 1322 /* Verify a few of the more important attributes */
1325 if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { 1323 if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
1326 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1324 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
1327 if (!data_unstable) 1325 if (!data_unstable)
1328 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; 1326 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
1329 } 1327 }
1328
1329 cur_size = i_size_read(inode);
1330 new_isize = nfs_size_to_loff_t(fattr->size);
1330 if (cur_size != new_isize) { 1331 if (cur_size != new_isize) {
1331 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1332 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
1332 if (nfsi->npages == 0) 1333 if (nfsi->npages == 0)
@@ -1343,6 +1344,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
1343 if (inode->i_nlink != fattr->nlink) 1344 if (inode->i_nlink != fattr->nlink)
1344 nfsi->cache_validity |= NFS_INO_INVALID_ATTR; 1345 nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
1345 1346
1347out:
1346 if (!timespec_equal(&inode->i_atime, &fattr->atime)) 1348 if (!timespec_equal(&inode->i_atime, &fattr->atime))
1347 nfsi->cache_validity |= NFS_INO_INVALID_ATIME; 1349 nfsi->cache_validity |= NFS_INO_INVALID_ATIME;
1348 1350
@@ -1481,15 +1483,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1481 nfsi->cache_change_attribute = jiffies; 1483 nfsi->cache_change_attribute = jiffies;
1482 } 1484 }
1483 1485
1484 if ((fattr->valid & NFS_ATTR_FATTR_V4)
1485 && nfsi->change_attr != fattr->change_attr) {
1486 dprintk("NFS: change_attr change on server for file %s/%ld\n",
1487 inode->i_sb->s_id, inode->i_ino);
1488 nfsi->change_attr = fattr->change_attr;
1489 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1490 nfsi->cache_change_attribute = jiffies;
1491 }
1492
1493 /* If ctime has changed we should definitely clear access+acl caches */ 1486 /* If ctime has changed we should definitely clear access+acl caches */
1494 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { 1487 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
1495 invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1488 invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
@@ -1519,6 +1512,17 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1519 inode->i_blksize = fattr->du.nfs2.blocksize; 1512 inode->i_blksize = fattr->du.nfs2.blocksize;
1520 } 1513 }
1521 1514
1515 if ((fattr->valid & NFS_ATTR_FATTR_V4)) {
1516 if (nfsi->change_attr != fattr->change_attr) {
1517 dprintk("NFS: change_attr change on server for file %s/%ld\n",
1518 inode->i_sb->s_id, inode->i_ino);
1519 nfsi->change_attr = fattr->change_attr;
1520 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1521 nfsi->cache_change_attribute = jiffies;
1522 } else
1523 invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA);
1524 }
1525
1522 /* Update attrtimeo value if we're out of the unstable period */ 1526 /* Update attrtimeo value if we're out of the unstable period */
1523 if (invalid & NFS_INO_INVALID_ATTR) { 1527 if (invalid & NFS_INO_INVALID_ATTR) {
1524 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); 1528 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);