diff options
-rw-r--r-- | fs/nfs/inode.c | 40 | ||||
-rw-r--r-- | include/linux/nfs_fs.h | 3 |
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 | |||
476 | struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) | 476 | struct 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 | ||
483 | void put_nfs_open_context(struct nfs_open_context *ctx) | 483 | static 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 | |||
503 | void 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 | ||
71 | struct nfs4_state; | 72 | struct nfs4_state; |
72 | struct nfs_open_context { | 73 | struct 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; |