3.10-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Trond Myklebust <trond.mykleb...@primarydata.com>

commit 43b6535e717d2f656f71d9bd16022136b781c934 upstream.

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 <kinglong...@gmail.com>
Signed-off-by: Trond Myklebust <trond.mykleb...@primarydata.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 fs/nfs/inode.c |   26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1382,18 +1382,20 @@ static int nfs_update_inode(struct inode
                        inode->i_version = fattr->change_attr;
                }
        } else if (server->caps & NFS_CAP_CHANGE_ATTR)
-               invalid |= save_cache_validity;
+               nfsi->cache_validity |= save_cache_validity;
 
        if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
                memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
        } else if (server->caps & NFS_CAP_MTIME)
-               invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+               nfsi->cache_validity |= save_cache_validity &
+                               (NFS_INO_INVALID_ATTR
                                | NFS_INO_REVAL_FORCED);
 
        if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
                memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
        } else if (server->caps & NFS_CAP_CTIME)
-               invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+               nfsi->cache_validity |= save_cache_validity &
+                               (NFS_INO_INVALID_ATTR
                                | NFS_INO_REVAL_FORCED);
 
        /* Check if our cached file size is stale */
@@ -1416,7 +1418,8 @@ static int nfs_update_inode(struct inode
                                        (long long)new_isize);
                }
        } else
-               invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+               nfsi->cache_validity |= save_cache_validity &
+                               (NFS_INO_INVALID_ATTR
                                | NFS_INO_REVAL_PAGECACHE
                                | NFS_INO_REVAL_FORCED);
 
@@ -1424,7 +1427,8 @@ static int nfs_update_inode(struct inode
        if (fattr->valid & NFS_ATTR_FATTR_ATIME)
                memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
        else if (server->caps & NFS_CAP_ATIME)
-               invalid |= save_cache_validity & (NFS_INO_INVALID_ATIME
+               nfsi->cache_validity |= save_cache_validity &
+                               (NFS_INO_INVALID_ATIME
                                | NFS_INO_REVAL_FORCED);
 
        if (fattr->valid & NFS_ATTR_FATTR_MODE) {
@@ -1435,7 +1439,8 @@ static int nfs_update_inode(struct inode
                        invalid |= 
NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
                }
        } else if (server->caps & NFS_CAP_MODE)
-               invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+               nfsi->cache_validity |= save_cache_validity &
+                               (NFS_INO_INVALID_ATTR
                                | NFS_INO_INVALID_ACCESS
                                | NFS_INO_INVALID_ACL
                                | NFS_INO_REVAL_FORCED);
@@ -1446,7 +1451,8 @@ static int nfs_update_inode(struct inode
                        inode->i_uid = fattr->uid;
                }
        } else if (server->caps & NFS_CAP_OWNER)
-               invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+               nfsi->cache_validity |= save_cache_validity &
+                               (NFS_INO_INVALID_ATTR
                                | NFS_INO_INVALID_ACCESS
                                | NFS_INO_INVALID_ACL
                                | NFS_INO_REVAL_FORCED);
@@ -1457,7 +1463,8 @@ static int nfs_update_inode(struct inode
                        inode->i_gid = fattr->gid;
                }
        } else if (server->caps & NFS_CAP_OWNER_GROUP)
-               invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+               nfsi->cache_validity |= save_cache_validity &
+                               (NFS_INO_INVALID_ATTR
                                | NFS_INO_INVALID_ACCESS
                                | NFS_INO_INVALID_ACL
                                | NFS_INO_REVAL_FORCED);
@@ -1470,7 +1477,8 @@ static int nfs_update_inode(struct inode
                        set_nlink(inode, fattr->nlink);
                }
        } else if (server->caps & NFS_CAP_NLINK)
-               invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+               nfsi->cache_validity |= save_cache_validity &
+                               (NFS_INO_INVALID_ATTR
                                | NFS_INO_REVAL_FORCED);
 
        if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to