Merge tag 'clang-lto-v5.12-rc1-fix1' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / fs / nfs / inode.c
index 522aa10..749bbea 100644 (file)
@@ -195,6 +195,18 @@ bool nfs_check_cache_invalid(struct inode *inode, unsigned long flags)
 }
 EXPORT_SYMBOL_GPL(nfs_check_cache_invalid);
 
+#ifdef CONFIG_NFS_V4_2
+static bool nfs_has_xattr_cache(const struct nfs_inode *nfsi)
+{
+       return nfsi->xattr_cache != NULL;
+}
+#else
+static bool nfs_has_xattr_cache(const struct nfs_inode *nfsi)
+{
+       return false;
+}
+#endif
+
 static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
@@ -209,6 +221,8 @@ static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
                                | NFS_INO_INVALID_XATTR);
        }
 
+       if (!nfs_has_xattr_cache(nfsi))
+               flags &= ~NFS_INO_INVALID_XATTR;
        if (inode->i_mapping->nrpages == 0)
                flags &= ~(NFS_INO_INVALID_DATA|NFS_INO_DATA_INVAL_DEFER);
        nfsi->cache_validity |= flags;
@@ -594,7 +608,8 @@ EXPORT_SYMBOL_GPL(nfs_fhget);
 #define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN)
 
 int
-nfs_setattr(struct dentry *dentry, struct iattr *attr)
+nfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
+           struct iattr *attr)
 {
        struct inode *inode = d_inode(dentry);
        struct nfs_fattr *fattr;
@@ -787,8 +802,8 @@ static bool nfs_need_revalidate_inode(struct inode *inode)
        return false;
 }
 
-int nfs_getattr(const struct path *path, struct kstat *stat,
-               u32 request_mask, unsigned int query_flags)
+int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path,
+               struct kstat *stat, u32 request_mask, unsigned int query_flags)
 {
        struct inode *inode = d_inode(path->dentry);
        struct nfs_server *server = NFS_SERVER(inode);
@@ -857,7 +872,7 @@ out_no_revalidate:
        /* Only return attributes that were revalidated. */
        stat->result_mask &= request_mask;
 out_no_update:
-       generic_fillattr(inode, stat);
+       generic_fillattr(&init_user_ns, inode, stat);
        stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
        if (S_ISDIR(inode->i_mode))
                stat->blksize = NFS_SERVER(inode)->dtsize;
@@ -1257,55 +1272,19 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map
        return 0;
 }
 
-bool nfs_mapping_need_revalidate_inode(struct inode *inode)
-{
-       return nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE) ||
-               NFS_STALE(inode);
-}
-
-int nfs_revalidate_mapping_rcu(struct inode *inode)
-{
-       struct nfs_inode *nfsi = NFS_I(inode);
-       unsigned long *bitlock = &nfsi->flags;
-       int ret = 0;
-
-       if (IS_SWAPFILE(inode))
-               goto out;
-       if (nfs_mapping_need_revalidate_inode(inode)) {
-               ret = -ECHILD;
-               goto out;
-       }
-       spin_lock(&inode->i_lock);
-       if (test_bit(NFS_INO_INVALIDATING, bitlock) ||
-           (nfsi->cache_validity & NFS_INO_INVALID_DATA))
-               ret = -ECHILD;
-       spin_unlock(&inode->i_lock);
-out:
-       return ret;
-}
-
 /**
- * nfs_revalidate_mapping - Revalidate the pagecache
- * @inode: pointer to host inode
+ * nfs_clear_invalid_mapping - Conditionally clear a mapping
  * @mapping: pointer to mapping
+ *
+ * If the NFS_INO_INVALID_DATA inode flag is set, clear the mapping.
  */
-int nfs_revalidate_mapping(struct inode *inode,
-               struct address_space *mapping)
+int nfs_clear_invalid_mapping(struct address_space *mapping)
 {
+       struct inode *inode = mapping->host;
        struct nfs_inode *nfsi = NFS_I(inode);
        unsigned long *bitlock = &nfsi->flags;
        int ret = 0;
 
-       /* swapfiles are not supposed to be shared. */
-       if (IS_SWAPFILE(inode))
-               goto out;
-
-       if (nfs_mapping_need_revalidate_inode(inode)) {
-               ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
-               if (ret < 0)
-                       goto out;
-       }
-
        /*
         * We must clear NFS_INO_INVALID_DATA first to ensure that
         * invalidations that come in while we're shooting down the mappings
@@ -1336,8 +1315,8 @@ int nfs_revalidate_mapping(struct inode *inode,
 
        set_bit(NFS_INO_INVALIDATING, bitlock);
        smp_wmb();
-       nfsi->cache_validity &= ~(NFS_INO_INVALID_DATA|
-                       NFS_INO_DATA_INVAL_DEFER);
+       nfsi->cache_validity &=
+               ~(NFS_INO_INVALID_DATA | NFS_INO_DATA_INVAL_DEFER);
        spin_unlock(&inode->i_lock);
        trace_nfs_invalidate_mapping_enter(inode);
        ret = nfs_invalidate_mapping(inode, mapping);
@@ -1350,6 +1329,53 @@ out:
        return ret;
 }
 
+bool nfs_mapping_need_revalidate_inode(struct inode *inode)
+{
+       return nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE) ||
+               NFS_STALE(inode);
+}
+
+int nfs_revalidate_mapping_rcu(struct inode *inode)
+{
+       struct nfs_inode *nfsi = NFS_I(inode);
+       unsigned long *bitlock = &nfsi->flags;
+       int ret = 0;
+
+       if (IS_SWAPFILE(inode))
+               goto out;
+       if (nfs_mapping_need_revalidate_inode(inode)) {
+               ret = -ECHILD;
+               goto out;
+       }
+       spin_lock(&inode->i_lock);
+       if (test_bit(NFS_INO_INVALIDATING, bitlock) ||
+           (nfsi->cache_validity & NFS_INO_INVALID_DATA))
+               ret = -ECHILD;
+       spin_unlock(&inode->i_lock);
+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)
+{
+       /* swapfiles are not supposed to be shared. */
+       if (IS_SWAPFILE(inode))
+               return 0;
+
+       if (nfs_mapping_need_revalidate_inode(inode)) {
+               int ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return nfs_clear_invalid_mapping(mapping);
+}
+
 static bool nfs_file_has_writers(struct nfs_inode *nfsi)
 {
        struct inode *inode = &nfsi->vfs_inode;