aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-12-29 18:55:19 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-12-30 10:18:26 -0500
commitade14a7df796d4e86bd9d181193c883a57b13db0 (patch)
tree581a00d3e9f1355c496bd132ef2a84675ca9d0e8
parent5c5fc09a1157a11dbe84e6421c3e0b37d05238cb (diff)
NFS: Fix attribute cache revalidation
If a NFSv4 client uses the cache_consistency_bitmask in order to request only information about the change attribute, timestamps and size, then it has not revalidated all attributes, and hence the attribute timeout timestamp should not be updated. Reported-by: Donald Buczek <buczek@molgen.mpg.de> Cc: stable@vger.kernel.org Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--fs/nfs/inode.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index c7e8b87da5b2..3e2071a177fd 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1641,6 +1641,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1641 unsigned long invalid = 0; 1641 unsigned long invalid = 0;
1642 unsigned long now = jiffies; 1642 unsigned long now = jiffies;
1643 unsigned long save_cache_validity; 1643 unsigned long save_cache_validity;
1644 bool cache_revalidated = true;
1644 1645
1645 dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n", 1646 dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
1646 __func__, inode->i_sb->s_id, inode->i_ino, 1647 __func__, inode->i_sb->s_id, inode->i_ino,
@@ -1702,22 +1703,28 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1702 nfs_force_lookup_revalidate(inode); 1703 nfs_force_lookup_revalidate(inode);
1703 inode->i_version = fattr->change_attr; 1704 inode->i_version = fattr->change_attr;
1704 } 1705 }
1705 } else 1706 } else {
1706 nfsi->cache_validity |= save_cache_validity; 1707 nfsi->cache_validity |= save_cache_validity;
1708 cache_revalidated = false;
1709 }
1707 1710
1708 if (fattr->valid & NFS_ATTR_FATTR_MTIME) { 1711 if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
1709 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); 1712 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
1710 } else if (server->caps & NFS_CAP_MTIME) 1713 } else if (server->caps & NFS_CAP_MTIME) {
1711 nfsi->cache_validity |= save_cache_validity & 1714 nfsi->cache_validity |= save_cache_validity &
1712 (NFS_INO_INVALID_ATTR 1715 (NFS_INO_INVALID_ATTR
1713 | NFS_INO_REVAL_FORCED); 1716 | NFS_INO_REVAL_FORCED);
1717 cache_revalidated = false;
1718 }
1714 1719
1715 if (fattr->valid & NFS_ATTR_FATTR_CTIME) { 1720 if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
1716 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 1721 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
1717 } else if (server->caps & NFS_CAP_CTIME) 1722 } else if (server->caps & NFS_CAP_CTIME) {
1718 nfsi->cache_validity |= save_cache_validity & 1723 nfsi->cache_validity |= save_cache_validity &
1719 (NFS_INO_INVALID_ATTR 1724 (NFS_INO_INVALID_ATTR
1720 | NFS_INO_REVAL_FORCED); 1725 | NFS_INO_REVAL_FORCED);
1726 cache_revalidated = false;
1727 }
1721 1728
1722 /* Check if our cached file size is stale */ 1729 /* Check if our cached file size is stale */
1723 if (fattr->valid & NFS_ATTR_FATTR_SIZE) { 1730 if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
@@ -1737,19 +1744,23 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1737 (long long)cur_isize, 1744 (long long)cur_isize,
1738 (long long)new_isize); 1745 (long long)new_isize);
1739 } 1746 }
1740 } else 1747 } else {
1741 nfsi->cache_validity |= save_cache_validity & 1748 nfsi->cache_validity |= save_cache_validity &
1742 (NFS_INO_INVALID_ATTR 1749 (NFS_INO_INVALID_ATTR
1743 | NFS_INO_REVAL_PAGECACHE 1750 | NFS_INO_REVAL_PAGECACHE
1744 | NFS_INO_REVAL_FORCED); 1751 | NFS_INO_REVAL_FORCED);
1752 cache_revalidated = false;
1753 }
1745 1754
1746 1755
1747 if (fattr->valid & NFS_ATTR_FATTR_ATIME) 1756 if (fattr->valid & NFS_ATTR_FATTR_ATIME)
1748 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); 1757 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
1749 else if (server->caps & NFS_CAP_ATIME) 1758 else if (server->caps & NFS_CAP_ATIME) {
1750 nfsi->cache_validity |= save_cache_validity & 1759 nfsi->cache_validity |= save_cache_validity &
1751 (NFS_INO_INVALID_ATIME 1760 (NFS_INO_INVALID_ATIME
1752 | NFS_INO_REVAL_FORCED); 1761 | NFS_INO_REVAL_FORCED);
1762 cache_revalidated = false;
1763 }
1753 1764
1754 if (fattr->valid & NFS_ATTR_FATTR_MODE) { 1765 if (fattr->valid & NFS_ATTR_FATTR_MODE) {
1755 if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) { 1766 if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) {
@@ -1758,36 +1769,42 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1758 inode->i_mode = newmode; 1769 inode->i_mode = newmode;
1759 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1770 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1760 } 1771 }
1761 } else if (server->caps & NFS_CAP_MODE) 1772 } else if (server->caps & NFS_CAP_MODE) {
1762 nfsi->cache_validity |= save_cache_validity & 1773 nfsi->cache_validity |= save_cache_validity &
1763 (NFS_INO_INVALID_ATTR 1774 (NFS_INO_INVALID_ATTR
1764 | NFS_INO_INVALID_ACCESS 1775 | NFS_INO_INVALID_ACCESS
1765 | NFS_INO_INVALID_ACL 1776 | NFS_INO_INVALID_ACL
1766 | NFS_INO_REVAL_FORCED); 1777 | NFS_INO_REVAL_FORCED);
1778 cache_revalidated = false;
1779 }
1767 1780
1768 if (fattr->valid & NFS_ATTR_FATTR_OWNER) { 1781 if (fattr->valid & NFS_ATTR_FATTR_OWNER) {
1769 if (!uid_eq(inode->i_uid, fattr->uid)) { 1782 if (!uid_eq(inode->i_uid, fattr->uid)) {
1770 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1783 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1771 inode->i_uid = fattr->uid; 1784 inode->i_uid = fattr->uid;
1772 } 1785 }
1773 } else if (server->caps & NFS_CAP_OWNER) 1786 } else if (server->caps & NFS_CAP_OWNER) {
1774 nfsi->cache_validity |= save_cache_validity & 1787 nfsi->cache_validity |= save_cache_validity &
1775 (NFS_INO_INVALID_ATTR 1788 (NFS_INO_INVALID_ATTR
1776 | NFS_INO_INVALID_ACCESS 1789 | NFS_INO_INVALID_ACCESS
1777 | NFS_INO_INVALID_ACL 1790 | NFS_INO_INVALID_ACL
1778 | NFS_INO_REVAL_FORCED); 1791 | NFS_INO_REVAL_FORCED);
1792 cache_revalidated = false;
1793 }
1779 1794
1780 if (fattr->valid & NFS_ATTR_FATTR_GROUP) { 1795 if (fattr->valid & NFS_ATTR_FATTR_GROUP) {
1781 if (!gid_eq(inode->i_gid, fattr->gid)) { 1796 if (!gid_eq(inode->i_gid, fattr->gid)) {
1782 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1797 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1783 inode->i_gid = fattr->gid; 1798 inode->i_gid = fattr->gid;
1784 } 1799 }
1785 } else if (server->caps & NFS_CAP_OWNER_GROUP) 1800 } else if (server->caps & NFS_CAP_OWNER_GROUP) {
1786 nfsi->cache_validity |= save_cache_validity & 1801 nfsi->cache_validity |= save_cache_validity &
1787 (NFS_INO_INVALID_ATTR 1802 (NFS_INO_INVALID_ATTR
1788 | NFS_INO_INVALID_ACCESS 1803 | NFS_INO_INVALID_ACCESS
1789 | NFS_INO_INVALID_ACL 1804 | NFS_INO_INVALID_ACL
1790 | NFS_INO_REVAL_FORCED); 1805 | NFS_INO_REVAL_FORCED);
1806 cache_revalidated = false;
1807 }
1791 1808
1792 if (fattr->valid & NFS_ATTR_FATTR_NLINK) { 1809 if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
1793 if (inode->i_nlink != fattr->nlink) { 1810 if (inode->i_nlink != fattr->nlink) {
@@ -1796,19 +1813,22 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1796 invalid |= NFS_INO_INVALID_DATA; 1813 invalid |= NFS_INO_INVALID_DATA;
1797 set_nlink(inode, fattr->nlink); 1814 set_nlink(inode, fattr->nlink);
1798 } 1815 }
1799 } else if (server->caps & NFS_CAP_NLINK) 1816 } else if (server->caps & NFS_CAP_NLINK) {
1800 nfsi->cache_validity |= save_cache_validity & 1817 nfsi->cache_validity |= save_cache_validity &
1801 (NFS_INO_INVALID_ATTR 1818 (NFS_INO_INVALID_ATTR
1802 | NFS_INO_REVAL_FORCED); 1819 | NFS_INO_REVAL_FORCED);
1820 cache_revalidated = false;
1821 }
1803 1822
1804 if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { 1823 if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
1805 /* 1824 /*
1806 * report the blocks in 512byte units 1825 * report the blocks in 512byte units
1807 */ 1826 */
1808 inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used); 1827 inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
1809 } 1828 } else if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
1810 if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
1811 inode->i_blocks = fattr->du.nfs2.blocks; 1829 inode->i_blocks = fattr->du.nfs2.blocks;
1830 else
1831 cache_revalidated = false;
1812 1832
1813 /* Update attrtimeo value if we're out of the unstable period */ 1833 /* Update attrtimeo value if we're out of the unstable period */
1814 if (invalid & NFS_INO_INVALID_ATTR) { 1834 if (invalid & NFS_INO_INVALID_ATTR) {
@@ -1818,9 +1838,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1818 /* Set barrier to be more recent than all outstanding updates */ 1838 /* Set barrier to be more recent than all outstanding updates */
1819 nfsi->attr_gencount = nfs_inc_attr_generation_counter(); 1839 nfsi->attr_gencount = nfs_inc_attr_generation_counter();
1820 } else { 1840 } else {
1821 if (!time_in_range_open(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) { 1841 if (cache_revalidated) {
1822 if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode)) 1842 if (!time_in_range_open(now, nfsi->attrtimeo_timestamp,
1823 nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode); 1843 nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
1844 nfsi->attrtimeo <<= 1;
1845 if (nfsi->attrtimeo > NFS_MAXATTRTIMEO(inode))
1846 nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
1847 }
1824 nfsi->attrtimeo_timestamp = now; 1848 nfsi->attrtimeo_timestamp = now;
1825 } 1849 }
1826 /* Set the barrier to be more recent than this fattr */ 1850 /* Set the barrier to be more recent than this fattr */
@@ -1829,7 +1853,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1829 } 1853 }
1830 1854
1831 /* Don't declare attrcache up to date if there were no attrs! */ 1855 /* Don't declare attrcache up to date if there were no attrs! */
1832 if (fattr->valid != 0) 1856 if (cache_revalidated)
1833 invalid &= ~NFS_INO_INVALID_ATTR; 1857 invalid &= ~NFS_INO_INVALID_ATTR;
1834 1858
1835 /* Don't invalidate the data if we were to blame */ 1859 /* Don't invalidate the data if we were to blame */