NFS: Fix a few further cache consistency regressions

Steve Dickson writes:
Doing the following:
1. On server:
$ mkdir ~/t
$ echo Hello > ~/t/tmp

2. On client, wait for a string to appear in this file:
$ until grep -q foo t/tmp ; do echo -n . ; sleep 1 ; done

3. On server, create a *new* file with the same name containing that
string:
$ mv ~/t/tmp ~/t/tmp.old; echo foo > ~/t/tmp

will show how the client will never (and I mean never ;-) ) see
the updated file.

The problem is that we do not update nfsi->cache_change_attribute when the
file changes on the server (we only update it when our client makes the
changes). This again means that functions like nfs_check_verifier() will
fail to register when the parent directory has changed and should trigger
a dentry lookup revalidation.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

+20 -34
+20 -34
fs/nfs/inode.c
··· 54 #define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) 55 56 static void nfs_invalidate_inode(struct inode *); 57 - static int nfs_update_inode(struct inode *, struct nfs_fattr *, unsigned long); 58 59 static struct inode *nfs_alloc_inode(struct super_block *sb); 60 static void nfs_destroy_inode(struct inode *); ··· 1080 int status = -ESTALE; 1081 struct nfs_fattr fattr; 1082 struct nfs_inode *nfsi = NFS_I(inode); 1083 - unsigned long verifier; 1084 - unsigned long cache_validity; 1085 1086 dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", 1087 inode->i_sb->s_id, (long long)NFS_FILEID(inode)); ··· 1104 } 1105 } 1106 1107 - /* Protect against RPC races by saving the change attribute */ 1108 - verifier = nfs_save_change_attribute(inode); 1109 status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); 1110 if (status != 0) { 1111 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", ··· 1118 } 1119 1120 spin_lock(&inode->i_lock); 1121 - status = nfs_update_inode(inode, &fattr, verifier); 1122 if (status) { 1123 spin_unlock(&inode->i_lock); 1124 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", ··· 1126 (long long)NFS_FILEID(inode), status); 1127 goto out; 1128 } 1129 - cache_validity = nfsi->cache_validity; 1130 - nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; 1131 - 1132 - /* 1133 - * We may need to keep the attributes marked as invalid if 1134 - * we raced with nfs_end_attr_update(). 1135 - */ 1136 - if (time_after_eq(verifier, nfsi->cache_change_attribute)) 1137 - nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); 1138 spin_unlock(&inode->i_lock); 1139 1140 nfs_revalidate_mapping(inode, inode->i_mapping); 1141 1142 - if (cache_validity & NFS_INO_INVALID_ACL) 1143 nfs_zap_acl_cache(inode); 1144 1145 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", ··· 1333 return 0; 1334 spin_lock(&inode->i_lock); 1335 nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; 1336 - if (nfs_verify_change_attribute(inode, fattr->time_start)) 1337 - nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); 1338 if (time_after(fattr->time_start, nfsi->last_updated)) 1339 - status = nfs_update_inode(inode, fattr, fattr->time_start); 1340 else 1341 status = nfs_check_inode_attributes(inode, fattr); 1342 ··· 1360 nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; 1361 goto out; 1362 } 1363 - status = nfs_update_inode(inode, fattr, fattr->time_start); 1364 - if (time_after_eq(fattr->time_start, nfsi->cache_change_attribute)) 1365 - nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE); 1366 - nfsi->cache_change_attribute = jiffies; 1367 out: 1368 spin_unlock(&inode->i_lock); 1369 return status; ··· 1378 * 1379 * A very similar scenario holds for the dir cache. 1380 */ 1381 - static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier) 1382 { 1383 struct nfs_inode *nfsi = NFS_I(inode); 1384 loff_t cur_isize, new_isize; 1385 unsigned int invalid = 0; 1386 - int data_unstable; 1387 1388 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", 1389 __FUNCTION__, inode->i_sb->s_id, inode->i_ino, ··· 1414 nfsi->last_updated = jiffies; 1415 1416 /* Are we racing with known updates of the metadata on the server? */ 1417 - data_unstable = ! (nfs_verify_change_attribute(inode, verifier) || 1418 - (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)); 1419 1420 /* Check if our cached file size is stale */ 1421 new_isize = nfs_size_to_loff_t(fattr->size); ··· 1425 /* Do we perhaps have any outstanding writes? */ 1426 if (nfsi->npages == 0) { 1427 /* No, but did we race with nfs_end_data_update()? */ 1428 - if (time_after_eq(verifier, nfsi->cache_change_attribute)) { 1429 inode->i_size = new_isize; 1430 invalid |= NFS_INO_INVALID_DATA; 1431 } ··· 1434 inode->i_size = new_isize; 1435 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1436 } 1437 dprintk("NFS: isize change on server for file %s/%ld\n", 1438 inode->i_sb->s_id, inode->i_ino); 1439 } ··· 1444 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); 1445 dprintk("NFS: mtime change on server for file %s/%ld\n", 1446 inode->i_sb->s_id, inode->i_ino); 1447 - if (!data_unstable) 1448 - invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1449 } 1450 1451 if ((fattr->valid & NFS_ATTR_FATTR_V4) ··· 1453 dprintk("NFS: change_attr change on server for file %s/%ld\n", 1454 inode->i_sb->s_id, inode->i_ino); 1455 nfsi->change_attr = fattr->change_attr; 1456 - if (!data_unstable) 1457 - invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1458 } 1459 1460 /* If ctime has changed we should definitely clear access+acl caches */ 1461 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { 1462 - if (!data_unstable) 1463 - invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1464 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 1465 } 1466 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); 1467 ··· 1499 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) 1500 || S_ISLNK(inode->i_mode))) 1501 invalid &= ~NFS_INO_INVALID_DATA; 1502 if (!nfs_have_delegation(inode, FMODE_READ)) 1503 nfsi->cache_validity |= invalid; 1504
··· 54 #define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) 55 56 static void nfs_invalidate_inode(struct inode *); 57 + static int nfs_update_inode(struct inode *, struct nfs_fattr *); 58 59 static struct inode *nfs_alloc_inode(struct super_block *sb); 60 static void nfs_destroy_inode(struct inode *); ··· 1080 int status = -ESTALE; 1081 struct nfs_fattr fattr; 1082 struct nfs_inode *nfsi = NFS_I(inode); 1083 1084 dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", 1085 inode->i_sb->s_id, (long long)NFS_FILEID(inode)); ··· 1106 } 1107 } 1108 1109 status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); 1110 if (status != 0) { 1111 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", ··· 1122 } 1123 1124 spin_lock(&inode->i_lock); 1125 + status = nfs_update_inode(inode, &fattr); 1126 if (status) { 1127 spin_unlock(&inode->i_lock); 1128 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", ··· 1130 (long long)NFS_FILEID(inode), status); 1131 goto out; 1132 } 1133 spin_unlock(&inode->i_lock); 1134 1135 nfs_revalidate_mapping(inode, inode->i_mapping); 1136 1137 + if (nfsi->cache_validity & NFS_INO_INVALID_ACL) 1138 nfs_zap_acl_cache(inode); 1139 1140 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", ··· 1346 return 0; 1347 spin_lock(&inode->i_lock); 1348 nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; 1349 if (time_after(fattr->time_start, nfsi->last_updated)) 1350 + status = nfs_update_inode(inode, fattr); 1351 else 1352 status = nfs_check_inode_attributes(inode, fattr); 1353 ··· 1375 nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; 1376 goto out; 1377 } 1378 + status = nfs_update_inode(inode, fattr); 1379 out: 1380 spin_unlock(&inode->i_lock); 1381 return status; ··· 1396 * 1397 * A very similar scenario holds for the dir cache. 1398 */ 1399 + static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) 1400 { 1401 struct nfs_inode *nfsi = NFS_I(inode); 1402 loff_t cur_isize, new_isize; 1403 unsigned int invalid = 0; 1404 + int data_stable; 1405 1406 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", 1407 __FUNCTION__, inode->i_sb->s_id, inode->i_ino, ··· 1432 nfsi->last_updated = jiffies; 1433 1434 /* Are we racing with known updates of the metadata on the server? */ 1435 + data_stable = nfs_verify_change_attribute(inode, fattr->time_start); 1436 + if (data_stable) 1437 + nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); 1438 1439 /* Check if our cached file size is stale */ 1440 new_isize = nfs_size_to_loff_t(fattr->size); ··· 1442 /* Do we perhaps have any outstanding writes? */ 1443 if (nfsi->npages == 0) { 1444 /* No, but did we race with nfs_end_data_update()? */ 1445 + if (data_stable) { 1446 inode->i_size = new_isize; 1447 invalid |= NFS_INO_INVALID_DATA; 1448 } ··· 1451 inode->i_size = new_isize; 1452 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1453 } 1454 + nfsi->cache_change_attribute = jiffies; 1455 dprintk("NFS: isize change on server for file %s/%ld\n", 1456 inode->i_sb->s_id, inode->i_ino); 1457 } ··· 1460 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); 1461 dprintk("NFS: mtime change on server for file %s/%ld\n", 1462 inode->i_sb->s_id, inode->i_ino); 1463 + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1464 + nfsi->cache_change_attribute = jiffies; 1465 } 1466 1467 if ((fattr->valid & NFS_ATTR_FATTR_V4) ··· 1469 dprintk("NFS: change_attr change on server for file %s/%ld\n", 1470 inode->i_sb->s_id, inode->i_ino); 1471 nfsi->change_attr = fattr->change_attr; 1472 + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1473 + nfsi->cache_change_attribute = jiffies; 1474 } 1475 1476 /* If ctime has changed we should definitely clear access+acl caches */ 1477 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { 1478 + invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1479 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 1480 + nfsi->cache_change_attribute = jiffies; 1481 } 1482 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); 1483 ··· 1515 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) 1516 || S_ISLNK(inode->i_mode))) 1517 invalid &= ~NFS_INO_INVALID_DATA; 1518 + if (data_stable) 1519 + invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE); 1520 if (!nfs_have_delegation(inode, FMODE_READ)) 1521 nfsi->cache_validity |= invalid; 1522