diff options
-rw-r--r-- | fs/nfs/inode.c | 44 |
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 | ||
1347 | out: | ||
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); |