[PATCH] NFS: Fix cache consistency races
authorTrond Myklebust <trond.myklebust@fys.uio.no>
Mon, 17 Oct 2005 10:02:00 +0000 (06:02 -0400)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 17 Oct 2005 21:47:16 +0000 (14:47 -0700)
If the data cache has been marked as potentially invalid by nfs_refresh_inode,
we should invalidate it rather than assume that changes are due to our own
activity.

Also ensure that we always start with a valid cache before declaring it
to be protected by a delegation.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/nfs/delegation.c
fs/nfs/file.c
fs/nfs/inode.c

index d7f7eb6..4a36839 100644 (file)
@@ -85,6 +85,10 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
        struct nfs_delegation *delegation;
        int status = 0;
 
+       /* Ensure we first revalidate the attributes and page cache! */
+       if ((nfsi->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_ATTR)))
+               __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+
        delegation = nfs_alloc_delegation();
        if (delegation == NULL)
                return -ENOMEM;
index f6b9eda..6bdcfa9 100644 (file)
@@ -137,7 +137,8 @@ static int nfs_revalidate_file(struct inode *inode, struct file *filp)
        struct nfs_inode *nfsi = NFS_I(inode);
        int retval = 0;
 
-       if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) || nfs_attribute_timeout(inode))
+       if ((nfsi->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_ATTR))
+                       || nfs_attribute_timeout(inode))
                retval = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
        nfs_revalidate_mapping(inode, filp->f_mapping);
        return 0;
index 6922469..6be46d2 100644 (file)
@@ -1226,10 +1226,6 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
        loff_t cur_size, new_isize;
        int data_unstable;
 
-       /* Do we hold a delegation? */
-       if (nfs_have_delegation(inode, FMODE_READ))
-               return 0;
-
        spin_lock(&inode->i_lock);
 
        /* Are we in the process of updating data on the server? */
@@ -1350,7 +1346,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
        nfsi->read_cache_jiffies = fattr->timestamp;
 
        /* Are we racing with known updates of the metadata on the server? */
-       data_unstable = ! nfs_verify_change_attribute(inode, verifier);
+       data_unstable = ! (nfs_verify_change_attribute(inode, verifier) ||
+               (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE));
 
        /* Check if our cached file size is stale */
        new_isize = nfs_size_to_loff_t(fattr->size);