]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/nfs/inode.c
mtd: bcm47xxsflash: use platform_(set|get)_drvdata
[karo-tx-linux.git] / fs / nfs / inode.c
index ce42dd00e4ee5f1131715d1ea23c2a5792ea0c73..5ca4d96b19421881c6b3b0fba493e605d6d70eeb 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/compat.h>
 #include <linux/freezer.h>
 
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 #include "nfs4_fs.h"
 #include "callback.h"
@@ -160,6 +160,43 @@ int nfs_sync_mapping(struct address_space *mapping)
        return ret;
 }
 
+static int nfs_attribute_timeout(struct inode *inode)
+{
+       struct nfs_inode *nfsi = NFS_I(inode);
+
+       return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
+}
+
+static bool nfs_check_cache_invalid_delegated(struct inode *inode, unsigned long flags)
+{
+       unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
+
+       /* Special case for the pagecache or access cache */
+       if (flags == NFS_INO_REVAL_PAGECACHE &&
+           !(cache_validity & NFS_INO_REVAL_FORCED))
+               return false;
+       return (cache_validity & flags) != 0;
+}
+
+static bool nfs_check_cache_invalid_not_delegated(struct inode *inode, unsigned long flags)
+{
+       unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
+
+       if ((cache_validity & flags) != 0)
+               return true;
+       if (nfs_attribute_timeout(inode))
+               return true;
+       return false;
+}
+
+bool nfs_check_cache_invalid(struct inode *inode, unsigned long flags)
+{
+       if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
+               return nfs_check_cache_invalid_delegated(inode, flags);
+
+       return nfs_check_cache_invalid_not_delegated(inode, flags);
+}
+
 static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
@@ -634,15 +671,28 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
 }
 EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
 
-static void nfs_request_parent_use_readdirplus(struct dentry *dentry)
+static void nfs_readdirplus_parent_cache_miss(struct dentry *dentry)
 {
        struct dentry *parent;
 
+       if (!nfs_server_capable(d_inode(dentry), NFS_CAP_READDIRPLUS))
+               return;
        parent = dget_parent(dentry);
        nfs_force_use_readdirplus(d_inode(parent));
        dput(parent);
 }
 
+static void nfs_readdirplus_parent_cache_hit(struct dentry *dentry)
+{
+       struct dentry *parent;
+
+       if (!nfs_server_capable(d_inode(dentry), NFS_CAP_READDIRPLUS))
+               return;
+       parent = dget_parent(dentry);
+       nfs_advise_use_readdirplus(d_inode(parent));
+       dput(parent);
+}
+
 static bool nfs_need_revalidate_inode(struct inode *inode)
 {
        if (NFS_I(inode)->cache_validity &
@@ -683,10 +733,10 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
        if (need_atime || nfs_need_revalidate_inode(inode)) {
                struct nfs_server *server = NFS_SERVER(inode);
 
-               if (server->caps & NFS_CAP_READDIRPLUS)
-                       nfs_request_parent_use_readdirplus(dentry);
+               nfs_readdirplus_parent_cache_miss(dentry);
                err = __nfs_revalidate_inode(server, inode);
-       }
+       } else
+               nfs_readdirplus_parent_cache_hit(dentry);
        if (!err) {
                generic_fillattr(inode, stat);
                stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
@@ -702,8 +752,7 @@ EXPORT_SYMBOL_GPL(nfs_getattr);
 static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
 {
        atomic_set(&l_ctx->count, 1);
-       l_ctx->lockowner.l_owner = current->files;
-       l_ctx->lockowner.l_pid = current->tgid;
+       l_ctx->lockowner = current->files;
        INIT_LIST_HEAD(&l_ctx->list);
        atomic_set(&l_ctx->io_count, 0);
 }
@@ -714,9 +763,7 @@ static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context
        struct nfs_lock_context *pos = head;
 
        do {
-               if (pos->lockowner.l_owner != current->files)
-                       continue;
-               if (pos->lockowner.l_pid != current->tgid)
+               if (pos->lockowner != current->files)
                        continue;
                atomic_inc(&pos->count);
                return pos;
@@ -785,6 +832,8 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
        if (!is_sync)
                return;
        inode = d_inode(ctx->dentry);
+       if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
+               return;
        nfsi = NFS_I(inode);
        if (inode->i_mapping->nrpages == 0)
                return;
@@ -799,7 +848,9 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
 }
 EXPORT_SYMBOL_GPL(nfs_close_context);
 
-struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode)
+struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry,
+                                               fmode_t f_mode,
+                                               struct file *filp)
 {
        struct nfs_open_context *ctx;
        struct rpc_cred *cred = rpc_lookup_cred();
@@ -818,6 +869,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f
        ctx->mode = f_mode;
        ctx->flags = 0;
        ctx->error = 0;
+       ctx->flock_owner = (fl_owner_t)filp;
        nfs_init_lock_context(&ctx->lock_context);
        ctx->lock_context.open_context = ctx;
        INIT_LIST_HEAD(&ctx->list);
@@ -942,7 +994,7 @@ int nfs_open(struct inode *inode, struct file *filp)
 {
        struct nfs_open_context *ctx;
 
-       ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode);
+       ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode, filp);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
        nfs_file_set_open_context(filp, ctx);
@@ -1031,13 +1083,6 @@ out:
        return status;
 }
 
-int nfs_attribute_timeout(struct inode *inode)
-{
-       struct nfs_inode *nfsi = NFS_I(inode);
-
-       return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
-}
-
 int nfs_attribute_cache_expired(struct inode *inode)
 {
        if (nfs_have_delegated_attributes(inode))
@@ -1060,15 +1105,6 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
 }
 EXPORT_SYMBOL_GPL(nfs_revalidate_inode);
 
-int nfs_revalidate_inode_rcu(struct nfs_server *server, struct inode *inode)
-{
-       if (!(NFS_I(inode)->cache_validity &
-                       (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL))
-                       && !nfs_attribute_cache_expired(inode))
-               return NFS_STALE(inode) ? -ESTALE : 0;
-       return -ECHILD;
-}
-
 static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
@@ -1099,13 +1135,10 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map
        return 0;
 }
 
-static bool nfs_mapping_need_revalidate_inode(struct inode *inode)
+bool nfs_mapping_need_revalidate_inode(struct inode *inode)
 {
-       if (nfs_have_delegated_attributes(inode))
-               return false;
-       return (NFS_I(inode)->cache_validity & NFS_INO_REVAL_PAGECACHE)
-               || nfs_attribute_timeout(inode)
-               || NFS_STALE(inode);
+       return nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE) ||
+               NFS_STALE(inode);
 }
 
 int nfs_revalidate_mapping_rcu(struct inode *inode)
@@ -1317,7 +1350,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
                invalid |= NFS_INO_INVALID_ATIME;
 
        if (invalid != 0)
-               nfs_set_cache_invalid(inode, invalid);
+               nfs_set_cache_invalid(inode, invalid | NFS_INO_REVAL_FORCED);
 
        nfsi->read_cache_jiffies = fattr->time_start;
        return 0;
@@ -1517,13 +1550,6 @@ static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr
 {
        unsigned long invalid = NFS_INO_INVALID_ATTR;
 
-       /*
-        * Don't revalidate the pagecache if we hold a delegation, but do
-        * force an attribute update
-        */
-       if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
-               invalid = NFS_INO_INVALID_ATTR|NFS_INO_REVAL_FORCED;
-
        if (S_ISDIR(inode->i_mode))
                invalid |= NFS_INO_INVALID_DATA;
        nfs_set_cache_invalid(inode, invalid);