aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/inode.c40
-rw-r--r--include/linux/nfs_fs.h3
2 files changed, 25 insertions, 18 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index e7d2bba900b5..01fc8ab0c562 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -461,7 +461,6 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str
461 461
462 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); 462 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
463 if (ctx != NULL) { 463 if (ctx != NULL) {
464 atomic_set(&ctx->count, 1);
465 ctx->path.dentry = dget(dentry); 464 ctx->path.dentry = dget(dentry);
466 ctx->path.mnt = mntget(mnt); 465 ctx->path.mnt = mntget(mnt);
467 ctx->cred = get_rpccred(cred); 466 ctx->cred = get_rpccred(cred);
@@ -469,6 +468,7 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str
469 ctx->lockowner = current->files; 468 ctx->lockowner = current->files;
470 ctx->error = 0; 469 ctx->error = 0;
471 ctx->dir_cookie = 0; 470 ctx->dir_cookie = 0;
471 kref_init(&ctx->kref);
472 } 472 }
473 return ctx; 473 return ctx;
474} 474}
@@ -476,27 +476,33 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str
476struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) 476struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
477{ 477{
478 if (ctx != NULL) 478 if (ctx != NULL)
479 atomic_inc(&ctx->count); 479 kref_get(&ctx->kref);
480 return ctx; 480 return ctx;
481} 481}
482 482
483void put_nfs_open_context(struct nfs_open_context *ctx) 483static void nfs_free_open_context(struct kref *kref)
484{ 484{
485 if (atomic_dec_and_test(&ctx->count)) { 485 struct nfs_open_context *ctx = container_of(kref,
486 if (!list_empty(&ctx->list)) { 486 struct nfs_open_context, kref);
487 struct inode *inode = ctx->path.dentry->d_inode; 487
488 spin_lock(&inode->i_lock); 488 if (!list_empty(&ctx->list)) {
489 list_del(&ctx->list); 489 struct inode *inode = ctx->path.dentry->d_inode;
490 spin_unlock(&inode->i_lock); 490 spin_lock(&inode->i_lock);
491 } 491 list_del(&ctx->list);
492 if (ctx->state != NULL) 492 spin_unlock(&inode->i_lock);
493 nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
494 if (ctx->cred != NULL)
495 put_rpccred(ctx->cred);
496 dput(ctx->path.dentry);
497 mntput(ctx->path.mnt);
498 kfree(ctx);
499 } 493 }
494 if (ctx->state != NULL)
495 nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
496 if (ctx->cred != NULL)
497 put_rpccred(ctx->cred);
498 dput(ctx->path.dentry);
499 mntput(ctx->path.mnt);
500 kfree(ctx);
501}
502
503void put_nfs_open_context(struct nfs_open_context *ctx)
504{
505 kref_put(&ctx->kref, nfs_free_open_context);
500} 506}
501 507
502/* 508/*
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 750708ccd708..bf24151d63be 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -30,6 +30,7 @@
30#ifdef __KERNEL__ 30#ifdef __KERNEL__
31 31
32#include <linux/in.h> 32#include <linux/in.h>
33#include <linux/kref.h>
33#include <linux/mm.h> 34#include <linux/mm.h>
34#include <linux/namei.h> 35#include <linux/namei.h>
35#include <linux/pagemap.h> 36#include <linux/pagemap.h>
@@ -70,7 +71,7 @@ struct nfs_access_entry {
70 71
71struct nfs4_state; 72struct nfs4_state;
72struct nfs_open_context { 73struct nfs_open_context {
73 atomic_t count; 74 struct kref kref;
74 struct path path; 75 struct path path;
75 struct rpc_cred *cred; 76 struct rpc_cred *cred;
76 struct nfs4_state *state; 77 struct nfs4_state *state;