vfs: trivial __d_lookup_rcu() cleanups
[linux-2.6.git] / fs / nfs / inode.c
index 3f1eb81..f649fba 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/nfs_xdr.h>
 #include <linux/slab.h>
 #include <linux/compat.h>
+#include <linux/freezer.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -56,7 +57,7 @@
 #define NFS_64_BIT_INODE_NUMBERS_ENABLED       1
 
 /* Default is to see 64-bit inode numbers */
-static int enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED;
+static bool enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED;
 
 static void nfs_invalidate_inode(struct inode *);
 static int nfs_update_inode(struct inode *, struct nfs_fattr *);
@@ -77,7 +78,7 @@ int nfs_wait_bit_killable(void *word)
 {
        if (fatal_signal_pending(current))
                return -ERESTARTSYS;
-       schedule();
+       freezable_schedule();
        return 0;
 }
 
@@ -256,7 +257,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
 
        nfs_attr_check_mountpoint(sb, fattr);
 
-       if ((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0 && (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0)
+       if (((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0) &&
+           !nfs_attr_use_mounted_on_fileid(fattr))
                goto out_no_inode;
        if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0)
                goto out_no_inode;
@@ -290,7 +292,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                 */
                inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops;
                if (S_ISREG(inode->i_mode)) {
-                       inode->i_fop = &nfs_file_operations;
+                       inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops;
                        inode->i_data.a_ops = &nfs_file_aops;
                        inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info;
                } else if (S_ISDIR(inode->i_mode)) {
@@ -317,9 +319,9 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                memset(&inode->i_atime, 0, sizeof(inode->i_atime));
                memset(&inode->i_mtime, 0, sizeof(inode->i_mtime));
                memset(&inode->i_ctime, 0, sizeof(inode->i_ctime));
-               nfsi->change_attr = 0;
+               inode->i_version = 0;
                inode->i_size = 0;
-               inode->i_nlink = 0;
+               clear_nlink(inode);
                inode->i_uid = -2;
                inode->i_gid = -2;
                inode->i_blocks = 0;
@@ -343,7 +345,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                                | NFS_INO_INVALID_ACCESS
                                | NFS_INO_INVALID_ACL;
                if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
-                       nfsi->change_attr = fattr->change_attr;
+                       inode->i_version = fattr->change_attr;
                else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR))
                        nfsi->cache_validity |= NFS_INO_INVALID_ATTR
                                | NFS_INO_INVALID_DATA;
@@ -354,7 +356,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                                | NFS_INO_INVALID_DATA
                                | NFS_INO_REVAL_PAGECACHE;
                if (fattr->valid & NFS_ATTR_FATTR_NLINK)
-                       inode->i_nlink = fattr->nlink;
+                       set_nlink(inode, fattr->nlink);
                else if (nfs_server_capable(inode, NFS_CAP_NLINK))
                        nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
                if (fattr->valid & NFS_ATTR_FATTR_OWNER)
@@ -566,7 +568,7 @@ static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context
 struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx)
 {
        struct nfs_lock_context *res, *new = NULL;
-       struct inode *inode = ctx->path.dentry->d_inode;
+       struct inode *inode = ctx->dentry->d_inode;
 
        spin_lock(&inode->i_lock);
        res = __nfs_find_lock_context(ctx);
@@ -593,7 +595,7 @@ struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx)
 void nfs_put_lock_context(struct nfs_lock_context *l_ctx)
 {
        struct nfs_open_context *ctx = l_ctx->open_context;
-       struct inode *inode = ctx->path.dentry->d_inode;
+       struct inode *inode = ctx->dentry->d_inode;
 
        if (!atomic_dec_and_lock(&l_ctx->count, &inode->i_lock))
                return;
@@ -619,7 +621,7 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
                return;
        if (!is_sync)
                return;
-       inode = ctx->path.dentry->d_inode;
+       inode = ctx->dentry->d_inode;
        if (!list_empty(&NFS_I(inode)->open_files))
                return;
        server = NFS_SERVER(inode);
@@ -628,23 +630,28 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
        nfs_revalidate_inode(server, inode);
 }
 
-struct nfs_open_context *alloc_nfs_open_context(struct path *path, struct rpc_cred *cred, fmode_t f_mode)
+struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode)
 {
        struct nfs_open_context *ctx;
+       struct rpc_cred *cred = rpc_lookup_cred();
+       if (IS_ERR(cred))
+               return ERR_CAST(cred);
 
        ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
-       if (ctx != NULL) {
-               ctx->path = *path;
-               path_get(&ctx->path);
-               ctx->cred = get_rpccred(cred);
-               ctx->state = NULL;
-               ctx->mode = f_mode;
-               ctx->flags = 0;
-               ctx->error = 0;
-               nfs_init_lock_context(&ctx->lock_context);
-               ctx->lock_context.open_context = ctx;
-               INIT_LIST_HEAD(&ctx->list);
+       if (!ctx) {
+               put_rpccred(cred);
+               return ERR_PTR(-ENOMEM);
        }
+       nfs_sb_active(dentry->d_sb);
+       ctx->dentry = dget(dentry);
+       ctx->cred = cred;
+       ctx->state = NULL;
+       ctx->mode = f_mode;
+       ctx->flags = 0;
+       ctx->error = 0;
+       nfs_init_lock_context(&ctx->lock_context);
+       ctx->lock_context.open_context = ctx;
+       INIT_LIST_HEAD(&ctx->list);
        return ctx;
 }
 
@@ -657,7 +664,8 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
 
 static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
 {
-       struct inode *inode = ctx->path.dentry->d_inode;
+       struct inode *inode = ctx->dentry->d_inode;
+       struct super_block *sb = ctx->dentry->d_sb;
 
        if (!list_empty(&ctx->list)) {
                if (!atomic_dec_and_lock(&ctx->lock_context.count, &inode->i_lock))
@@ -670,7 +678,8 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
                NFS_PROTO(inode)->close_context(ctx, is_sync);
        if (ctx->cred != NULL)
                put_rpccred(ctx->cred);
-       path_put(&ctx->path);
+       dput(ctx->dentry);
+       nfs_sb_deactive(sb);
        kfree(ctx);
 }
 
@@ -735,15 +744,10 @@ static void nfs_file_clear_open_context(struct file *filp)
 int nfs_open(struct inode *inode, struct file *filp)
 {
        struct nfs_open_context *ctx;
-       struct rpc_cred *cred;
 
-       cred = rpc_lookup_cred();
-       if (IS_ERR(cred))
-               return PTR_ERR(cred);
-       ctx = alloc_nfs_open_context(&filp->f_path, cred, filp->f_mode);
-       put_rpccred(cred);
-       if (ctx == NULL)
-               return -ENOMEM;
+       ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode);
+       if (IS_ERR(ctx))
+               return PTR_ERR(ctx);
        nfs_file_set_open_context(filp, ctx);
        put_nfs_open_context(ctx);
        nfs_fscache_set_inode_cookie(inode, filp);
@@ -894,8 +898,8 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
 
        if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
                        && (fattr->valid & NFS_ATTR_FATTR_CHANGE)
-                       && nfsi->change_attr == fattr->pre_change_attr) {
-               nfsi->change_attr = fattr->change_attr;
+                       && inode->i_version == fattr->pre_change_attr) {
+               inode->i_version = fattr->change_attr;
                if (S_ISDIR(inode->i_mode))
                        nfsi->cache_validity |= NFS_INO_INVALID_DATA;
                ret |= NFS_INO_INVALID_ATTR;
@@ -949,7 +953,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
                return -EIO;
 
        if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
-                       nfsi->change_attr != fattr->change_attr)
+                       inode->i_version != fattr->change_attr)
                invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
 
        /* Verify a few of the more important attributes */
@@ -1016,6 +1020,8 @@ void nfs_fattr_init(struct nfs_fattr *fattr)
        fattr->valid = 0;
        fattr->time_start = jiffies;
        fattr->gencount = nfs_inc_attr_generation_counter();
+       fattr->owner_name = NULL;
+       fattr->group_name = NULL;
 }
 
 struct nfs_fattr *nfs_alloc_fattr(void)
@@ -1160,7 +1166,7 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa
        }
        if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
                        (fattr->valid & NFS_ATTR_FATTR_PRECHANGE) == 0) {
-               fattr->pre_change_attr = NFS_I(inode)->change_attr;
+               fattr->pre_change_attr = inode->i_version;
                fattr->valid |= NFS_ATTR_FATTR_PRECHANGE;
        }
        if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 &&
@@ -1241,13 +1247,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 
        /* More cache consistency checks */
        if (fattr->valid & NFS_ATTR_FATTR_CHANGE) {
-               if (nfsi->change_attr != fattr->change_attr) {
+               if (inode->i_version != fattr->change_attr) {
                        dprintk("NFS: change_attr change on server for file %s/%ld\n",
                                        inode->i_sb->s_id, inode->i_ino);
                        invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
                        if (S_ISDIR(inode->i_mode))
                                nfs_force_lookup_revalidate(inode);
-                       nfsi->change_attr = fattr->change_attr;
+                       inode->i_version = fattr->change_attr;
                }
        } else if (server->caps & NFS_CAP_CHANGE_ATTR)
                invalid |= save_cache_validity;
@@ -1358,7 +1364,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                        invalid |= NFS_INO_INVALID_ATTR;
                        if (S_ISDIR(inode->i_mode))
                                invalid |= NFS_INO_INVALID_DATA;
-                       inode->i_nlink = fattr->nlink;
+                       set_nlink(inode, fattr->nlink);
                }
        } else if (server->caps & NFS_CAP_NLINK)
                invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
@@ -1461,7 +1467,6 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
 static void nfs_i_callback(struct rcu_head *head)
 {
        struct inode *inode = container_of(head, struct inode, i_rcu);
-       INIT_LIST_HEAD(&inode->i_dentry);
        kmem_cache_free(nfs_inode_cachep, NFS_I(inode));
 }