aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2018-03-20 16:53:31 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2018-04-10 16:06:22 -0400
commit16e143751727471f9a565515344196693bbc8762 (patch)
treeeb6905af5fe0ad1f65b2392656f0bd218a8f5a03
parentcac88f942d5890706a8965e40a068d295ac95ae2 (diff)
NFS: More fine grained attribute tracking
Currently, if the NFS_INO_INVALID_ATTR flag is set, for instance by a call to nfs_post_op_update_inode_locked(), then it will not be cleared until all the attributes have been revalidated. This means, for instance, that NFSv4 writes will always force a full attribute revalidation. Track the ctime, mtime, size and change attribute separately from the other attributes so that we can have nfs_post_op_update_inode_locked() set them correctly, and later have the cache consistency bitmask be able to clear them. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--fs/nfs/dir.c4
-rw-r--r--fs/nfs/inode.c109
-rw-r--r--fs/nfs/nfs4proc.c7
-rw-r--r--fs/nfs/write.c7
-rw-r--r--include/linux/nfs_fs.h21
5 files changed, 94 insertions, 54 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 8001f8c7ad0e..73f8b43d988c 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1272,7 +1272,9 @@ static void nfs_drop_nlink(struct inode *inode)
1272 /* drop the inode if we're reasonably sure this is the last link */ 1272 /* drop the inode if we're reasonably sure this is the last link */
1273 if (inode->i_nlink == 1) 1273 if (inode->i_nlink == 1)
1274 clear_nlink(inode); 1274 clear_nlink(inode);
1275 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR; 1275 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_CHANGE
1276 | NFS_INO_INVALID_CTIME
1277 | NFS_INO_INVALID_OTHER;
1276 spin_unlock(&inode->i_lock); 1278 spin_unlock(&inode->i_lock);
1277} 1279}
1278 1280
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 6e5a96e2e9a0..23880f45c1e4 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -452,7 +452,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
452 inode->i_mode = fattr->mode; 452 inode->i_mode = fattr->mode;
453 if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0 453 if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0
454 && nfs_server_capable(inode, NFS_CAP_MODE)) 454 && nfs_server_capable(inode, NFS_CAP_MODE))
455 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); 455 nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER);
456 /* Why so? Because we want revalidate for devices/FIFOs, and 456 /* Why so? Because we want revalidate for devices/FIFOs, and
457 * that's precisely what we have in nfs_file_inode_operations. 457 * that's precisely what we have in nfs_file_inode_operations.
458 */ 458 */
@@ -498,37 +498,35 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
498 if (fattr->valid & NFS_ATTR_FATTR_ATIME) 498 if (fattr->valid & NFS_ATTR_FATTR_ATIME)
499 inode->i_atime = fattr->atime; 499 inode->i_atime = fattr->atime;
500 else if (nfs_server_capable(inode, NFS_CAP_ATIME)) 500 else if (nfs_server_capable(inode, NFS_CAP_ATIME))
501 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); 501 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME);
502 if (fattr->valid & NFS_ATTR_FATTR_MTIME) 502 if (fattr->valid & NFS_ATTR_FATTR_MTIME)
503 inode->i_mtime = fattr->mtime; 503 inode->i_mtime = fattr->mtime;
504 else if (nfs_server_capable(inode, NFS_CAP_MTIME)) 504 else if (nfs_server_capable(inode, NFS_CAP_MTIME))
505 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); 505 nfs_set_cache_invalid(inode, NFS_INO_INVALID_MTIME);
506 if (fattr->valid & NFS_ATTR_FATTR_CTIME) 506 if (fattr->valid & NFS_ATTR_FATTR_CTIME)
507 inode->i_ctime = fattr->ctime; 507 inode->i_ctime = fattr->ctime;
508 else if (nfs_server_capable(inode, NFS_CAP_CTIME)) 508 else if (nfs_server_capable(inode, NFS_CAP_CTIME))
509 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); 509 nfs_set_cache_invalid(inode, NFS_INO_INVALID_CTIME);
510 if (fattr->valid & NFS_ATTR_FATTR_CHANGE) 510 if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
511 inode_set_iversion_raw(inode, fattr->change_attr); 511 inode_set_iversion_raw(inode, fattr->change_attr);
512 else 512 else
513 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR 513 nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE);
514 | NFS_INO_REVAL_PAGECACHE);
515 if (fattr->valid & NFS_ATTR_FATTR_SIZE) 514 if (fattr->valid & NFS_ATTR_FATTR_SIZE)
516 inode->i_size = nfs_size_to_loff_t(fattr->size); 515 inode->i_size = nfs_size_to_loff_t(fattr->size);
517 else 516 else
518 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR 517 nfs_set_cache_invalid(inode, NFS_INO_INVALID_SIZE);
519 | NFS_INO_REVAL_PAGECACHE);
520 if (fattr->valid & NFS_ATTR_FATTR_NLINK) 518 if (fattr->valid & NFS_ATTR_FATTR_NLINK)
521 set_nlink(inode, fattr->nlink); 519 set_nlink(inode, fattr->nlink);
522 else if (nfs_server_capable(inode, NFS_CAP_NLINK)) 520 else if (nfs_server_capable(inode, NFS_CAP_NLINK))
523 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); 521 nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER);
524 if (fattr->valid & NFS_ATTR_FATTR_OWNER) 522 if (fattr->valid & NFS_ATTR_FATTR_OWNER)
525 inode->i_uid = fattr->uid; 523 inode->i_uid = fattr->uid;
526 else if (nfs_server_capable(inode, NFS_CAP_OWNER)) 524 else if (nfs_server_capable(inode, NFS_CAP_OWNER))
527 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); 525 nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER);
528 if (fattr->valid & NFS_ATTR_FATTR_GROUP) 526 if (fattr->valid & NFS_ATTR_FATTR_GROUP)
529 inode->i_gid = fattr->gid; 527 inode->i_gid = fattr->gid;
530 else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP)) 528 else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
531 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); 529 nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER);
532 if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) 530 if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
533 inode->i_blocks = fattr->du.nfs2.blocks; 531 inode->i_blocks = fattr->du.nfs2.blocks;
534 if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { 532 if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
@@ -657,6 +655,7 @@ out:
657 * nfs_setattr_update_inode - Update inode metadata after a setattr call. 655 * nfs_setattr_update_inode - Update inode metadata after a setattr call.
658 * @inode: pointer to struct inode 656 * @inode: pointer to struct inode
659 * @attr: pointer to struct iattr 657 * @attr: pointer to struct iattr
658 * @fattr: pointer to struct nfs_fattr
660 * 659 *
661 * Note: we do this in the *proc.c in order to ensure that 660 * Note: we do this in the *proc.c in order to ensure that
662 * it works for things like exclusive creates too. 661 * it works for things like exclusive creates too.
@@ -669,6 +668,8 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
669 668
670 spin_lock(&inode->i_lock); 669 spin_lock(&inode->i_lock);
671 NFS_I(inode)->attr_gencount = fattr->gencount; 670 NFS_I(inode)->attr_gencount = fattr->gencount;
671 nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE
672 | NFS_INO_INVALID_CTIME);
672 if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) { 673 if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) {
673 if ((attr->ia_valid & ATTR_MODE) != 0) { 674 if ((attr->ia_valid & ATTR_MODE) != 0) {
674 int mode = attr->ia_mode & S_IALLUGO; 675 int mode = attr->ia_mode & S_IALLUGO;
@@ -683,13 +684,12 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
683 | NFS_INO_INVALID_ACL); 684 | NFS_INO_INVALID_ACL);
684 } 685 }
685 if ((attr->ia_valid & ATTR_SIZE) != 0) { 686 if ((attr->ia_valid & ATTR_SIZE) != 0) {
687 nfs_set_cache_invalid(inode, NFS_INO_INVALID_MTIME);
686 nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC); 688 nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC);
687 nfs_vmtruncate(inode, attr->ia_size); 689 nfs_vmtruncate(inode, attr->ia_size);
688 } 690 }
689 if (fattr->valid) 691 if (fattr->valid)
690 nfs_update_inode(inode, fattr); 692 nfs_update_inode(inode, fattr);
691 else
692 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
693 spin_unlock(&inode->i_lock); 693 spin_unlock(&inode->i_lock);
694} 694}
695EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); 695EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
@@ -1361,33 +1361,41 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
1361 if (!nfs_file_has_buffered_writers(nfsi)) { 1361 if (!nfs_file_has_buffered_writers(nfsi)) {
1362 /* Verify a few of the more important attributes */ 1362 /* Verify a few of the more important attributes */
1363 if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && !inode_eq_iversion_raw(inode, fattr->change_attr)) 1363 if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && !inode_eq_iversion_raw(inode, fattr->change_attr))
1364 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_REVAL_PAGECACHE; 1364 invalid |= NFS_INO_INVALID_CHANGE
1365 | NFS_INO_REVAL_PAGECACHE;
1365 1366
1366 if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec_equal(&inode->i_mtime, &fattr->mtime)) 1367 if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec_equal(&inode->i_mtime, &fattr->mtime))
1367 invalid |= NFS_INO_INVALID_ATTR; 1368 invalid |= NFS_INO_INVALID_MTIME;
1368 1369
1369 if ((fattr->valid & NFS_ATTR_FATTR_CTIME) && !timespec_equal(&inode->i_ctime, &fattr->ctime)) 1370 if ((fattr->valid & NFS_ATTR_FATTR_CTIME) && !timespec_equal(&inode->i_ctime, &fattr->ctime))
1370 invalid |= NFS_INO_INVALID_ATTR; 1371 invalid |= NFS_INO_INVALID_CTIME;
1371 1372
1372 if (fattr->valid & NFS_ATTR_FATTR_SIZE) { 1373 if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
1373 cur_size = i_size_read(inode); 1374 cur_size = i_size_read(inode);
1374 new_isize = nfs_size_to_loff_t(fattr->size); 1375 new_isize = nfs_size_to_loff_t(fattr->size);
1375 if (cur_size != new_isize) 1376 if (cur_size != new_isize)
1376 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; 1377 invalid |= NFS_INO_INVALID_SIZE
1378 | NFS_INO_REVAL_PAGECACHE;
1377 } 1379 }
1378 } 1380 }
1379 1381
1380 /* Have any file permissions changed? */ 1382 /* Have any file permissions changed? */
1381 if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) 1383 if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO))
1382 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; 1384 invalid |= NFS_INO_INVALID_ACCESS
1385 | NFS_INO_INVALID_ACL
1386 | NFS_INO_INVALID_OTHER;
1383 if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, fattr->uid)) 1387 if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, fattr->uid))
1384 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; 1388 invalid |= NFS_INO_INVALID_ACCESS
1389 | NFS_INO_INVALID_ACL
1390 | NFS_INO_INVALID_OTHER;
1385 if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, fattr->gid)) 1391 if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, fattr->gid))
1386 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; 1392 invalid |= NFS_INO_INVALID_ACCESS
1393 | NFS_INO_INVALID_ACL
1394 | NFS_INO_INVALID_OTHER;
1387 1395
1388 /* Has the link count changed? */ 1396 /* Has the link count changed? */
1389 if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink) 1397 if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
1390 invalid |= NFS_INO_INVALID_ATTR; 1398 invalid |= NFS_INO_INVALID_OTHER;
1391 1399
1392 if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec_equal(&inode->i_atime, &fattr->atime)) 1400 if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec_equal(&inode->i_atime, &fattr->atime))
1393 invalid |= NFS_INO_INVALID_ATIME; 1401 invalid |= NFS_INO_INVALID_ATIME;
@@ -1589,10 +1597,9 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
1589} 1597}
1590EXPORT_SYMBOL_GPL(nfs_refresh_inode); 1598EXPORT_SYMBOL_GPL(nfs_refresh_inode);
1591 1599
1592static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr) 1600static int nfs_post_op_update_inode_locked(struct inode *inode,
1601 struct nfs_fattr *fattr, unsigned int invalid)
1593{ 1602{
1594 unsigned long invalid = NFS_INO_INVALID_ATTR;
1595
1596 if (S_ISDIR(inode->i_mode)) 1603 if (S_ISDIR(inode->i_mode))
1597 invalid |= NFS_INO_INVALID_DATA; 1604 invalid |= NFS_INO_INVALID_DATA;
1598 nfs_set_cache_invalid(inode, invalid); 1605 nfs_set_cache_invalid(inode, invalid);
@@ -1621,7 +1628,9 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1621 1628
1622 spin_lock(&inode->i_lock); 1629 spin_lock(&inode->i_lock);
1623 nfs_fattr_set_barrier(fattr); 1630 nfs_fattr_set_barrier(fattr);
1624 status = nfs_post_op_update_inode_locked(inode, fattr); 1631 status = nfs_post_op_update_inode_locked(inode, fattr,
1632 NFS_INO_INVALID_CHANGE
1633 | NFS_INO_INVALID_CTIME);
1625 spin_unlock(&inode->i_lock); 1634 spin_unlock(&inode->i_lock);
1626 1635
1627 return status; 1636 return status;
@@ -1673,7 +1682,10 @@ int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fa
1673 fattr->valid |= NFS_ATTR_FATTR_PRESIZE; 1682 fattr->valid |= NFS_ATTR_FATTR_PRESIZE;
1674 } 1683 }
1675out_noforce: 1684out_noforce:
1676 status = nfs_post_op_update_inode_locked(inode, fattr); 1685 status = nfs_post_op_update_inode_locked(inode, fattr,
1686 NFS_INO_INVALID_CHANGE
1687 | NFS_INO_INVALID_CTIME
1688 | NFS_INO_INVALID_MTIME);
1677 return status; 1689 return status;
1678} 1690}
1679 1691
@@ -1795,12 +1807,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1795 inode->i_sb->s_id, inode->i_ino); 1807 inode->i_sb->s_id, inode->i_ino);
1796 /* Could it be a race with writeback? */ 1808 /* Could it be a race with writeback? */
1797 if (!have_writers) { 1809 if (!have_writers) {
1798 invalid |= NFS_INO_INVALID_ATTR 1810 invalid |= NFS_INO_INVALID_CHANGE
1799 | NFS_INO_INVALID_DATA 1811 | NFS_INO_INVALID_DATA
1800 | NFS_INO_INVALID_ACCESS 1812 | NFS_INO_INVALID_ACCESS
1801 | NFS_INO_INVALID_ACL; 1813 | NFS_INO_INVALID_ACL;
1802 /* Force revalidate of all attributes */ 1814 /* Force revalidate of all attributes */
1803 save_cache_validity |= NFS_INO_INVALID_ATTR; 1815 save_cache_validity |= NFS_INO_INVALID_CTIME
1816 | NFS_INO_INVALID_MTIME
1817 | NFS_INO_INVALID_SIZE
1818 | NFS_INO_INVALID_OTHER;
1804 if (S_ISDIR(inode->i_mode)) 1819 if (S_ISDIR(inode->i_mode))
1805 nfs_force_lookup_revalidate(inode); 1820 nfs_force_lookup_revalidate(inode);
1806 } 1821 }
@@ -1808,7 +1823,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1808 } 1823 }
1809 } else { 1824 } else {
1810 nfsi->cache_validity |= save_cache_validity & 1825 nfsi->cache_validity |= save_cache_validity &
1811 (NFS_INO_INVALID_ATTR 1826 (NFS_INO_INVALID_CHANGE
1812 | NFS_INO_REVAL_PAGECACHE 1827 | NFS_INO_REVAL_PAGECACHE
1813 | NFS_INO_REVAL_FORCED); 1828 | NFS_INO_REVAL_FORCED);
1814 cache_revalidated = false; 1829 cache_revalidated = false;
@@ -1818,7 +1833,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1818 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); 1833 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
1819 } else if (server->caps & NFS_CAP_MTIME) { 1834 } else if (server->caps & NFS_CAP_MTIME) {
1820 nfsi->cache_validity |= save_cache_validity & 1835 nfsi->cache_validity |= save_cache_validity &
1821 (NFS_INO_INVALID_ATTR 1836 (NFS_INO_INVALID_MTIME
1822 | NFS_INO_REVAL_FORCED); 1837 | NFS_INO_REVAL_FORCED);
1823 cache_revalidated = false; 1838 cache_revalidated = false;
1824 } 1839 }
@@ -1827,7 +1842,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1827 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 1842 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
1828 } else if (server->caps & NFS_CAP_CTIME) { 1843 } else if (server->caps & NFS_CAP_CTIME) {
1829 nfsi->cache_validity |= save_cache_validity & 1844 nfsi->cache_validity |= save_cache_validity &
1830 (NFS_INO_INVALID_ATTR 1845 (NFS_INO_INVALID_CTIME
1831 | NFS_INO_REVAL_FORCED); 1846 | NFS_INO_REVAL_FORCED);
1832 cache_revalidated = false; 1847 cache_revalidated = false;
1833 } 1848 }
@@ -1842,7 +1857,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1842 if (!nfs_have_writebacks(inode) || new_isize > cur_isize) { 1857 if (!nfs_have_writebacks(inode) || new_isize > cur_isize) {
1843 i_size_write(inode, new_isize); 1858 i_size_write(inode, new_isize);
1844 if (!have_writers) 1859 if (!have_writers)
1845 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1860 invalid |= NFS_INO_INVALID_DATA;
1846 } 1861 }
1847 dprintk("NFS: isize change on server for file %s/%ld " 1862 dprintk("NFS: isize change on server for file %s/%ld "
1848 "(%Ld to %Ld)\n", 1863 "(%Ld to %Ld)\n",
@@ -1853,7 +1868,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1853 } 1868 }
1854 } else { 1869 } else {
1855 nfsi->cache_validity |= save_cache_validity & 1870 nfsi->cache_validity |= save_cache_validity &
1856 (NFS_INO_INVALID_ATTR 1871 (NFS_INO_INVALID_SIZE
1857 | NFS_INO_REVAL_PAGECACHE 1872 | NFS_INO_REVAL_PAGECACHE
1858 | NFS_INO_REVAL_FORCED); 1873 | NFS_INO_REVAL_FORCED);
1859 cache_revalidated = false; 1874 cache_revalidated = false;
@@ -1874,55 +1889,61 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1874 umode_t newmode = inode->i_mode & S_IFMT; 1889 umode_t newmode = inode->i_mode & S_IFMT;
1875 newmode |= fattr->mode & S_IALLUGO; 1890 newmode |= fattr->mode & S_IALLUGO;
1876 inode->i_mode = newmode; 1891 inode->i_mode = newmode;
1877 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1892 invalid |= NFS_INO_INVALID_ACCESS
1893 | NFS_INO_INVALID_ACL
1894 | NFS_INO_INVALID_OTHER;
1878 } 1895 }
1879 } else if (server->caps & NFS_CAP_MODE) { 1896 } else if (server->caps & NFS_CAP_MODE) {
1880 nfsi->cache_validity |= save_cache_validity & 1897 nfsi->cache_validity |= save_cache_validity &
1881 (NFS_INO_INVALID_ATTR 1898 (NFS_INO_INVALID_ACCESS
1882 | NFS_INO_INVALID_ACCESS
1883 | NFS_INO_INVALID_ACL 1899 | NFS_INO_INVALID_ACL
1900 | NFS_INO_INVALID_OTHER
1884 | NFS_INO_REVAL_FORCED); 1901 | NFS_INO_REVAL_FORCED);
1885 cache_revalidated = false; 1902 cache_revalidated = false;
1886 } 1903 }
1887 1904
1888 if (fattr->valid & NFS_ATTR_FATTR_OWNER) { 1905 if (fattr->valid & NFS_ATTR_FATTR_OWNER) {
1889 if (!uid_eq(inode->i_uid, fattr->uid)) { 1906 if (!uid_eq(inode->i_uid, fattr->uid)) {
1890 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1907 invalid |= NFS_INO_INVALID_ACCESS
1908 | NFS_INO_INVALID_ACL
1909 | NFS_INO_INVALID_OTHER;
1891 inode->i_uid = fattr->uid; 1910 inode->i_uid = fattr->uid;
1892 } 1911 }
1893 } else if (server->caps & NFS_CAP_OWNER) { 1912 } else if (server->caps & NFS_CAP_OWNER) {
1894 nfsi->cache_validity |= save_cache_validity & 1913 nfsi->cache_validity |= save_cache_validity &
1895 (NFS_INO_INVALID_ATTR 1914 (NFS_INO_INVALID_ACCESS
1896 | NFS_INO_INVALID_ACCESS
1897 | NFS_INO_INVALID_ACL 1915 | NFS_INO_INVALID_ACL
1916 | NFS_INO_INVALID_OTHER
1898 | NFS_INO_REVAL_FORCED); 1917 | NFS_INO_REVAL_FORCED);
1899 cache_revalidated = false; 1918 cache_revalidated = false;
1900 } 1919 }
1901 1920
1902 if (fattr->valid & NFS_ATTR_FATTR_GROUP) { 1921 if (fattr->valid & NFS_ATTR_FATTR_GROUP) {
1903 if (!gid_eq(inode->i_gid, fattr->gid)) { 1922 if (!gid_eq(inode->i_gid, fattr->gid)) {
1904 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1923 invalid |= NFS_INO_INVALID_ACCESS
1924 | NFS_INO_INVALID_ACL
1925 | NFS_INO_INVALID_OTHER;
1905 inode->i_gid = fattr->gid; 1926 inode->i_gid = fattr->gid;
1906 } 1927 }
1907 } else if (server->caps & NFS_CAP_OWNER_GROUP) { 1928 } else if (server->caps & NFS_CAP_OWNER_GROUP) {
1908 nfsi->cache_validity |= save_cache_validity & 1929 nfsi->cache_validity |= save_cache_validity &
1909 (NFS_INO_INVALID_ATTR 1930 (NFS_INO_INVALID_ACCESS
1910 | NFS_INO_INVALID_ACCESS
1911 | NFS_INO_INVALID_ACL 1931 | NFS_INO_INVALID_ACL
1932 | NFS_INO_INVALID_OTHER
1912 | NFS_INO_REVAL_FORCED); 1933 | NFS_INO_REVAL_FORCED);
1913 cache_revalidated = false; 1934 cache_revalidated = false;
1914 } 1935 }
1915 1936
1916 if (fattr->valid & NFS_ATTR_FATTR_NLINK) { 1937 if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
1917 if (inode->i_nlink != fattr->nlink) { 1938 if (inode->i_nlink != fattr->nlink) {
1918 invalid |= NFS_INO_INVALID_ATTR; 1939 invalid |= NFS_INO_INVALID_OTHER;
1919 if (S_ISDIR(inode->i_mode)) 1940 if (S_ISDIR(inode->i_mode))
1920 invalid |= NFS_INO_INVALID_DATA; 1941 invalid |= NFS_INO_INVALID_DATA;
1921 set_nlink(inode, fattr->nlink); 1942 set_nlink(inode, fattr->nlink);
1922 } 1943 }
1923 } else if (server->caps & NFS_CAP_NLINK) { 1944 } else if (server->caps & NFS_CAP_NLINK) {
1924 nfsi->cache_validity |= save_cache_validity & 1945 nfsi->cache_validity |= save_cache_validity &
1925 (NFS_INO_INVALID_ATTR 1946 (NFS_INO_INVALID_OTHER
1926 | NFS_INO_REVAL_FORCED); 1947 | NFS_INO_REVAL_FORCED);
1927 cache_revalidated = false; 1948 cache_revalidated = false;
1928 } 1949 }
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 24b5c80b8128..e5ad2c186927 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1045,7 +1045,9 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo,
1045 struct nfs_inode *nfsi = NFS_I(dir); 1045 struct nfs_inode *nfsi = NFS_I(dir);
1046 1046
1047 spin_lock(&dir->i_lock); 1047 spin_lock(&dir->i_lock);
1048 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1048 nfsi->cache_validity |= NFS_INO_INVALID_CTIME
1049 | NFS_INO_INVALID_MTIME
1050 | NFS_INO_INVALID_DATA;
1049 if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(dir)) { 1051 if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(dir)) {
1050 nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; 1052 nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
1051 nfsi->attrtimeo_timestamp = jiffies; 1053 nfsi->attrtimeo_timestamp = jiffies;
@@ -5364,7 +5366,8 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
5364 * so mark the attribute cache invalid. 5366 * so mark the attribute cache invalid.
5365 */ 5367 */
5366 spin_lock(&inode->i_lock); 5368 spin_lock(&inode->i_lock);
5367 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR; 5369 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_CHANGE
5370 | NFS_INO_INVALID_CTIME;
5368 spin_unlock(&inode->i_lock); 5371 spin_unlock(&inode->i_lock);
5369 nfs_access_zap_cache(inode); 5372 nfs_access_zap_cache(inode);
5370 nfs_zap_acl_cache(inode); 5373 nfs_zap_acl_cache(inode);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 7428a669d7a7..3efce54ef1cd 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1562,8 +1562,11 @@ static int nfs_writeback_done(struct rpc_task *task,
1562 } 1562 }
1563 1563
1564 /* Deal with the suid/sgid bit corner case */ 1564 /* Deal with the suid/sgid bit corner case */
1565 if (nfs_should_remove_suid(inode)) 1565 if (nfs_should_remove_suid(inode)) {
1566 nfs_mark_for_revalidate(inode); 1566 spin_lock(&inode->i_lock);
1567 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_OTHER;
1568 spin_unlock(&inode->i_lock);
1569 }
1567 return 0; 1570 return 0;
1568} 1571}
1569 1572
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 4afb11be73f4..2f129bbfaae8 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -198,7 +198,6 @@ struct nfs_inode {
198/* 198/*
199 * Cache validity bit flags 199 * Cache validity bit flags
200 */ 200 */
201#define NFS_INO_INVALID_ATTR BIT(0) /* cached attrs are invalid */
202#define NFS_INO_INVALID_DATA BIT(1) /* cached data is invalid */ 201#define NFS_INO_INVALID_DATA BIT(1) /* cached data is invalid */
203#define NFS_INO_INVALID_ATIME BIT(2) /* cached atime is invalid */ 202#define NFS_INO_INVALID_ATIME BIT(2) /* cached atime is invalid */
204#define NFS_INO_INVALID_ACCESS BIT(3) /* cached access cred invalid */ 203#define NFS_INO_INVALID_ACCESS BIT(3) /* cached access cred invalid */
@@ -206,6 +205,17 @@ struct nfs_inode {
206#define NFS_INO_REVAL_PAGECACHE BIT(5) /* must revalidate pagecache */ 205#define NFS_INO_REVAL_PAGECACHE BIT(5) /* must revalidate pagecache */
207#define NFS_INO_REVAL_FORCED BIT(6) /* force revalidation ignoring a delegation */ 206#define NFS_INO_REVAL_FORCED BIT(6) /* force revalidation ignoring a delegation */
208#define NFS_INO_INVALID_LABEL BIT(7) /* cached label is invalid */ 207#define NFS_INO_INVALID_LABEL BIT(7) /* cached label is invalid */
208#define NFS_INO_INVALID_CHANGE BIT(8) /* cached change is invalid */
209#define NFS_INO_INVALID_CTIME BIT(9) /* cached ctime is invalid */
210#define NFS_INO_INVALID_MTIME BIT(10) /* cached mtime is invalid */
211#define NFS_INO_INVALID_SIZE BIT(11) /* cached size is invalid */
212#define NFS_INO_INVALID_OTHER BIT(12) /* other attrs are invalid */
213
214#define NFS_INO_INVALID_ATTR (NFS_INO_INVALID_CHANGE \
215 | NFS_INO_INVALID_CTIME \
216 | NFS_INO_INVALID_MTIME \
217 | NFS_INO_INVALID_SIZE \
218 | NFS_INO_INVALID_OTHER) /* inode metadata is invalid */
209 219
210/* 220/*
211 * Bit offsets in flags field 221 * Bit offsets in flags field
@@ -292,10 +302,11 @@ static inline void nfs_mark_for_revalidate(struct inode *inode)
292 struct nfs_inode *nfsi = NFS_I(inode); 302 struct nfs_inode *nfsi = NFS_I(inode);
293 303
294 spin_lock(&inode->i_lock); 304 spin_lock(&inode->i_lock);
295 nfsi->cache_validity |= NFS_INO_INVALID_ATTR | 305 nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE
296 NFS_INO_REVAL_PAGECACHE | 306 | NFS_INO_INVALID_ACCESS
297 NFS_INO_INVALID_ACCESS | 307 | NFS_INO_INVALID_ACL
298 NFS_INO_INVALID_ACL; 308 | NFS_INO_INVALID_CHANGE
309 | NFS_INO_INVALID_CTIME;
299 if (S_ISDIR(inode->i_mode)) 310 if (S_ISDIR(inode->i_mode))
300 nfsi->cache_validity |= NFS_INO_INVALID_DATA; 311 nfsi->cache_validity |= NFS_INO_INVALID_DATA;
301 spin_unlock(&inode->i_lock); 312 spin_unlock(&inode->i_lock);