aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/inode.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2014-04-15 10:07:57 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-04-15 23:24:43 -0400
commit43b6535e717d2f656f71d9bd16022136b781c934 (patch)
treee54ce1a679c198a1ddde4d82abdd7ffc0e8a5a84 /fs/nfs/inode.c
parent4dfc7fdb9e261d77818616782ae1841a80e0fc83 (diff)
NFS: Don't declare inode uptodate unless all attributes were checked
Fix a bug, whereby nfs_update_inode() was declaring the inode to be up to date despite not having checked all the attributes. The bug occurs because the temporary variable in which we cache the validity information is 'sanitised' before reapplying to nfsi->cache_validity. Reported-by: Kinglong Mee <kinglongmee@gmail.com> Cc: stable@vger.kernel.org # 3.5+ Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r--fs/nfs/inode.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 0c438973f3c8..c79f3e767c8c 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1575,18 +1575,20 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1575 inode->i_version = fattr->change_attr; 1575 inode->i_version = fattr->change_attr;
1576 } 1576 }
1577 } else if (server->caps & NFS_CAP_CHANGE_ATTR) 1577 } else if (server->caps & NFS_CAP_CHANGE_ATTR)
1578 invalid |= save_cache_validity; 1578 nfsi->cache_validity |= save_cache_validity;
1579 1579
1580 if (fattr->valid & NFS_ATTR_FATTR_MTIME) { 1580 if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
1581 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); 1581 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
1582 } else if (server->caps & NFS_CAP_MTIME) 1582 } else if (server->caps & NFS_CAP_MTIME)
1583 invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR 1583 nfsi->cache_validity |= save_cache_validity &
1584 (NFS_INO_INVALID_ATTR
1584 | NFS_INO_REVAL_FORCED); 1585 | NFS_INO_REVAL_FORCED);
1585 1586
1586 if (fattr->valid & NFS_ATTR_FATTR_CTIME) { 1587 if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
1587 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 1588 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
1588 } else if (server->caps & NFS_CAP_CTIME) 1589 } else if (server->caps & NFS_CAP_CTIME)
1589 invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR 1590 nfsi->cache_validity |= save_cache_validity &
1591 (NFS_INO_INVALID_ATTR
1590 | NFS_INO_REVAL_FORCED); 1592 | NFS_INO_REVAL_FORCED);
1591 1593
1592 /* Check if our cached file size is stale */ 1594 /* Check if our cached file size is stale */
@@ -1608,7 +1610,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1608 (long long)new_isize); 1610 (long long)new_isize);
1609 } 1611 }
1610 } else 1612 } else
1611 invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR 1613 nfsi->cache_validity |= save_cache_validity &
1614 (NFS_INO_INVALID_ATTR
1612 | NFS_INO_REVAL_PAGECACHE 1615 | NFS_INO_REVAL_PAGECACHE
1613 | NFS_INO_REVAL_FORCED); 1616 | NFS_INO_REVAL_FORCED);
1614 1617
@@ -1616,7 +1619,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1616 if (fattr->valid & NFS_ATTR_FATTR_ATIME) 1619 if (fattr->valid & NFS_ATTR_FATTR_ATIME)
1617 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); 1620 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
1618 else if (server->caps & NFS_CAP_ATIME) 1621 else if (server->caps & NFS_CAP_ATIME)
1619 invalid |= save_cache_validity & (NFS_INO_INVALID_ATIME 1622 nfsi->cache_validity |= save_cache_validity &
1623 (NFS_INO_INVALID_ATIME
1620 | NFS_INO_REVAL_FORCED); 1624 | NFS_INO_REVAL_FORCED);
1621 1625
1622 if (fattr->valid & NFS_ATTR_FATTR_MODE) { 1626 if (fattr->valid & NFS_ATTR_FATTR_MODE) {
@@ -1627,7 +1631,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1627 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1631 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1628 } 1632 }
1629 } else if (server->caps & NFS_CAP_MODE) 1633 } else if (server->caps & NFS_CAP_MODE)
1630 invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR 1634 nfsi->cache_validity |= save_cache_validity &
1635 (NFS_INO_INVALID_ATTR
1631 | NFS_INO_INVALID_ACCESS 1636 | NFS_INO_INVALID_ACCESS
1632 | NFS_INO_INVALID_ACL 1637 | NFS_INO_INVALID_ACL
1633 | NFS_INO_REVAL_FORCED); 1638 | NFS_INO_REVAL_FORCED);
@@ -1638,7 +1643,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1638 inode->i_uid = fattr->uid; 1643 inode->i_uid = fattr->uid;
1639 } 1644 }
1640 } else if (server->caps & NFS_CAP_OWNER) 1645 } else if (server->caps & NFS_CAP_OWNER)
1641 invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR 1646 nfsi->cache_validity |= save_cache_validity &
1647 (NFS_INO_INVALID_ATTR
1642 | NFS_INO_INVALID_ACCESS 1648 | NFS_INO_INVALID_ACCESS
1643 | NFS_INO_INVALID_ACL 1649 | NFS_INO_INVALID_ACL
1644 | NFS_INO_REVAL_FORCED); 1650 | NFS_INO_REVAL_FORCED);
@@ -1649,7 +1655,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1649 inode->i_gid = fattr->gid; 1655 inode->i_gid = fattr->gid;
1650 } 1656 }
1651 } else if (server->caps & NFS_CAP_OWNER_GROUP) 1657 } else if (server->caps & NFS_CAP_OWNER_GROUP)
1652 invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR 1658 nfsi->cache_validity |= save_cache_validity &
1659 (NFS_INO_INVALID_ATTR
1653 | NFS_INO_INVALID_ACCESS 1660 | NFS_INO_INVALID_ACCESS
1654 | NFS_INO_INVALID_ACL 1661 | NFS_INO_INVALID_ACL
1655 | NFS_INO_REVAL_FORCED); 1662 | NFS_INO_REVAL_FORCED);
@@ -1662,7 +1669,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1662 set_nlink(inode, fattr->nlink); 1669 set_nlink(inode, fattr->nlink);
1663 } 1670 }
1664 } else if (server->caps & NFS_CAP_NLINK) 1671 } else if (server->caps & NFS_CAP_NLINK)
1665 invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR 1672 nfsi->cache_validity |= save_cache_validity &
1673 (NFS_INO_INVALID_ATTR
1666 | NFS_INO_REVAL_FORCED); 1674 | NFS_INO_REVAL_FORCED);
1667 1675
1668 if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { 1676 if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {