pNFS: Actively set attributes as invalid if LAYOUTCOMMIT is outstanding
[deliverable/linux.git] / fs / nfs / inode.c
index 4e65a5a8a01bc562e9a9387ae7814b4d496f34c8..bf4ec5ecc97e4571e3f971222c71f0519874682a 100644 (file)
@@ -282,6 +282,7 @@ nfs_init_locked(struct inode *inode, void *opaque)
        struct nfs_fattr        *fattr = desc->fattr;
 
        set_nfs_fileid(inode, fattr->fileid);
+       inode->i_mode = fattr->mode;
        nfs_copy_fh(NFS_FH(inode), desc->fh);
        return 0;
 }
@@ -661,9 +662,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
        trace_nfs_getattr_enter(inode);
        /* Flush out writes to the server in order to update c/mtime.  */
        if (S_ISREG(inode->i_mode)) {
-               inode_lock(inode);
-               err = nfs_sync_inode(inode);
-               inode_unlock(inode);
+               err = filemap_write_and_wait(inode->i_mapping);
                if (err)
                        goto out;
        }
@@ -974,6 +973,13 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
        if (NFS_STALE(inode))
                goto out;
 
+       /* pNFS: Attributes aren't updated until we layoutcommit */
+       if (S_ISREG(inode->i_mode)) {
+               status = pnfs_sync_inode(inode, false);
+               if (status)
+                       goto out;
+       }
+
        status = -ENOMEM;
        fattr = nfs_alloc_fattr();
        if (fattr == NULL)
@@ -1124,14 +1130,12 @@ out:
 }
 
 /**
- * __nfs_revalidate_mapping - Revalidate the pagecache
+ * nfs_revalidate_mapping - Revalidate the pagecache
  * @inode - pointer to host inode
  * @mapping - pointer to mapping
- * @may_lock - take inode->i_mutex?
  */
-static int __nfs_revalidate_mapping(struct inode *inode,
-               struct address_space *mapping,
-               bool may_lock)
+int nfs_revalidate_mapping(struct inode *inode,
+               struct address_space *mapping)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
        unsigned long *bitlock = &nfsi->flags;
@@ -1180,12 +1184,7 @@ static int __nfs_revalidate_mapping(struct inode *inode,
        nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
        spin_unlock(&inode->i_lock);
        trace_nfs_invalidate_mapping_enter(inode);
-       if (may_lock) {
-               inode_lock(inode);
-               ret = nfs_invalidate_mapping(inode, mapping);
-               inode_unlock(inode);
-       } else
-               ret = nfs_invalidate_mapping(inode, mapping);
+       ret = nfs_invalidate_mapping(inode, mapping);
        trace_nfs_invalidate_mapping_exit(inode, ret);
 
        clear_bit_unlock(NFS_INO_INVALIDATING, bitlock);
@@ -1195,29 +1194,6 @@ out:
        return ret;
 }
 
-/**
- * nfs_revalidate_mapping - Revalidate the pagecache
- * @inode - pointer to host inode
- * @mapping - pointer to mapping
- */
-int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
-{
-       return __nfs_revalidate_mapping(inode, mapping, false);
-}
-
-/**
- * nfs_revalidate_mapping_protected - Revalidate the pagecache
- * @inode - pointer to host inode
- * @mapping - pointer to mapping
- *
- * Differs from nfs_revalidate_mapping() in that it grabs the inode->i_mutex
- * while invalidating the mapping.
- */
-int nfs_revalidate_mapping_protected(struct inode *inode, struct address_space *mapping)
-{
-       return __nfs_revalidate_mapping(inode, mapping, true);
-}
-
 static bool nfs_file_has_writers(struct nfs_inode *nfsi)
 {
        struct inode *inode = &nfsi->vfs_inode;
@@ -1237,6 +1213,11 @@ static bool nfs_file_has_writers(struct nfs_inode *nfsi)
                        list)->mode & FMODE_WRITE) == FMODE_WRITE;
 }
 
+static bool nfs_file_has_buffered_writers(struct nfs_inode *nfsi)
+{
+       return nfs_file_has_writers(nfsi) && nfs_file_io_is_buffered(nfsi);
+}
+
 static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
@@ -1301,7 +1282,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
        if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
                return -EIO;
 
-       if (!nfs_file_has_writers(nfsi)) {
+       if (!nfs_file_has_buffered_writers(nfsi)) {
                /* Verify a few of the more important attributes */
                if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && inode->i_version != fattr->change_attr)
                        invalid |= NFS_INO_INVALID_ATTR | NFS_INO_REVAL_PAGECACHE;
@@ -1493,28 +1474,12 @@ static int nfs_inode_attrs_need_update(const struct inode *inode, const struct n
                ((long)nfsi->attr_gencount - (long)nfs_read_attr_generation_counter() > 0);
 }
 
-/*
- * Don't trust the change_attribute, mtime, ctime or size if
- * a pnfs LAYOUTCOMMIT is outstanding
- */
-static void nfs_inode_attrs_handle_layoutcommit(struct inode *inode,
-               struct nfs_fattr *fattr)
-{
-       if (pnfs_layoutcommit_outstanding(inode))
-               fattr->valid &= ~(NFS_ATTR_FATTR_CHANGE |
-                               NFS_ATTR_FATTR_MTIME |
-                               NFS_ATTR_FATTR_CTIME |
-                               NFS_ATTR_FATTR_SIZE);
-}
-
 static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
 {
        int ret;
 
        trace_nfs_refresh_inode_enter(inode);
 
-       nfs_inode_attrs_handle_layoutcommit(inode, fattr);
-
        if (nfs_inode_attrs_need_update(inode, fattr))
                ret = nfs_update_inode(inode, fattr);
        else
@@ -1699,7 +1664,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
        unsigned long invalid = 0;
        unsigned long now = jiffies;
        unsigned long save_cache_validity;
-       bool have_writers = nfs_file_has_writers(nfsi);
+       bool have_writers = nfs_file_has_buffered_writers(nfsi);
        bool cache_revalidated = true;
 
        dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
@@ -1749,6 +1714,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
        /* Do atomic weak cache consistency updates */
        invalid |= nfs_wcc_update_inode(inode, fattr);
 
+       if (pnfs_layoutcommit_outstanding(inode)) {
+               nfsi->cache_validity |= save_cache_validity & NFS_INO_INVALID_ATTR;
+               cache_revalidated = false;
+       }
+
        /* More cache consistency checks */
        if (fattr->valid & NFS_ATTR_FATTR_CHANGE) {
                if (inode->i_version != fattr->change_attr) {
This page took 0.02683 seconds and 5 git commands to generate.