__nfs_readpage_to_fscache(inode, page, sync);
 }
 
+/*
+ * Invalidate the contents of fscache for this inode.  This will not sleep.
+ */
+static inline void nfs_fscache_invalidate(struct inode *inode)
+{
+       fscache_invalidate(NFS_I(inode)->fscache);
+}
+
+/*
+ * Wait for an object to finish being invalidated.
+ */
+static inline void nfs_fscache_wait_on_invalidate(struct inode *inode)
+{
+       fscache_wait_on_invalidate(NFS_I(inode)->fscache);
+}
+
 /*
  * indicate the client caching state as readable text
  */
        return "no ";
 }
 
-
 #else /* CONFIG_NFS_FSCACHE */
 static inline int nfs_fscache_register(void) { return 0; }
 static inline void nfs_fscache_unregister(void) {}
 static inline void nfs_readpage_to_fscache(struct inode *inode,
                                           struct page *page, int sync) {}
 
+
+static inline void nfs_fscache_invalidate(struct inode *inode) {}
+
 static inline const char *nfs_server_fscache_state(struct nfs_server *server)
 {
        return "no ";
 
        nfsi->attrtimeo_timestamp = jiffies;
 
        memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf));
-       if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
+       if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) {
                nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
-       else
+               nfs_fscache_invalidate(inode);
+       } else {
                nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
+       }
 }
 
 void nfs_zap_caches(struct inode *inode)
        if (mapping->nrpages != 0) {
                spin_lock(&inode->i_lock);
                NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
+               nfs_fscache_invalidate(inode);
                spin_unlock(&inode->i_lock);
        }
 }
                memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
        spin_unlock(&inode->i_lock);
        nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
-       nfs_fscache_reset_inode_cookie(inode);
+       nfs_fscache_wait_on_invalidate(inode);
        dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
                        inode->i_sb->s_id, (long long)NFS_FILEID(inode));
        return 0;
                i_size_write(inode, nfs_size_to_loff_t(fattr->size));
                ret |= NFS_INO_INVALID_ATTR;
        }
+
+       if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
+               nfs_fscache_invalidate(inode);
+
        return ret;
 }
 
        struct nfs_inode *nfsi = NFS_I(inode);
 
        nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
-       if (S_ISDIR(inode->i_mode))
+       if (S_ISDIR(inode->i_mode)) {
                nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+               nfs_fscache_invalidate(inode);
+       }
        if ((fattr->valid & NFS_ATTR_FATTR) == 0)
                return 0;
        return nfs_refresh_inode_locked(inode, fattr);
                        (save_cache_validity & NFS_INO_REVAL_FORCED))
                nfsi->cache_validity |= invalid;
 
+       if (invalid & NFS_INO_INVALID_DATA)
+               nfs_fscache_invalidate(inode);
+
        return 0;
  out_err:
        /*