diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-06-17 16:02:44 -0400 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:28 -0400 |
| commit | c6d00e639bdec5f33460bc95bae4efda7177a6ed (patch) | |
| tree | 86c00c756f3212ea54203dc62619f5cd6b4f153e | |
| parent | 3bec63db55463365110d00721ed60a31e4614cb6 (diff) | |
NFSv4: Convert struct nfs4_opendata to use struct kref
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
| -rw-r--r-- | fs/nfs/nfs4proc.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index fee2d14b158b..d90209e79587 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -214,7 +214,7 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) | |||
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | struct nfs4_opendata { | 216 | struct nfs4_opendata { |
| 217 | atomic_t count; | 217 | struct kref kref; |
| 218 | struct nfs_openargs o_arg; | 218 | struct nfs_openargs o_arg; |
| 219 | struct nfs_openres o_res; | 219 | struct nfs_openres o_res; |
| 220 | struct nfs_open_confirmargs c_arg; | 220 | struct nfs_open_confirmargs c_arg; |
| @@ -245,7 +245,6 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, | |||
| 245 | p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); | 245 | p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); |
| 246 | if (p->o_arg.seqid == NULL) | 246 | if (p->o_arg.seqid == NULL) |
| 247 | goto err_free; | 247 | goto err_free; |
| 248 | atomic_set(&p->count, 1); | ||
| 249 | p->path.mnt = mntget(path->mnt); | 248 | p->path.mnt = mntget(path->mnt); |
| 250 | p->path.dentry = dget(path->dentry); | 249 | p->path.dentry = dget(path->dentry); |
| 251 | p->dir = parent; | 250 | p->dir = parent; |
| @@ -275,6 +274,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, | |||
| 275 | p->c_arg.fh = &p->o_res.fh; | 274 | p->c_arg.fh = &p->o_res.fh; |
| 276 | p->c_arg.stateid = &p->o_res.stateid; | 275 | p->c_arg.stateid = &p->o_res.stateid; |
| 277 | p->c_arg.seqid = p->o_arg.seqid; | 276 | p->c_arg.seqid = p->o_arg.seqid; |
| 277 | kref_init(&p->kref); | ||
| 278 | return p; | 278 | return p; |
| 279 | err_free: | 279 | err_free: |
| 280 | kfree(p); | 280 | kfree(p); |
| @@ -283,16 +283,23 @@ err: | |||
| 283 | return NULL; | 283 | return NULL; |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | static void nfs4_opendata_free(struct nfs4_opendata *p) | 286 | static void nfs4_opendata_free(struct kref *kref) |
| 287 | { | 287 | { |
| 288 | if (p != NULL && atomic_dec_and_test(&p->count)) { | 288 | struct nfs4_opendata *p = container_of(kref, |
| 289 | nfs_free_seqid(p->o_arg.seqid); | 289 | struct nfs4_opendata, kref); |
| 290 | nfs4_put_state_owner(p->owner); | 290 | |
| 291 | dput(p->dir); | 291 | nfs_free_seqid(p->o_arg.seqid); |
| 292 | dput(p->path.dentry); | 292 | nfs4_put_state_owner(p->owner); |
| 293 | mntput(p->path.mnt); | 293 | dput(p->dir); |
| 294 | kfree(p); | 294 | dput(p->path.dentry); |
| 295 | } | 295 | mntput(p->path.mnt); |
| 296 | kfree(p); | ||
| 297 | } | ||
| 298 | |||
| 299 | static void nfs4_opendata_put(struct nfs4_opendata *p) | ||
| 300 | { | ||
| 301 | if (p != NULL) | ||
| 302 | kref_put(&p->kref, nfs4_opendata_free); | ||
| 296 | } | 303 | } |
| 297 | 304 | ||
| 298 | static int nfs4_wait_for_completion_rpc_task(struct rpc_task *task) | 305 | static int nfs4_wait_for_completion_rpc_task(struct rpc_task *task) |
| @@ -476,7 +483,7 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state | |||
| 476 | nfs_copy_fh(&opendata->o_res.fh, opendata->o_arg.fh); | 483 | nfs_copy_fh(&opendata->o_res.fh, opendata->o_arg.fh); |
| 477 | opendata->o_arg.u.delegation_type = delegation_type; | 484 | opendata->o_arg.u.delegation_type = delegation_type; |
| 478 | status = nfs4_open_recover(opendata, state); | 485 | status = nfs4_open_recover(opendata, state); |
| 479 | nfs4_opendata_free(opendata); | 486 | nfs4_opendata_put(opendata); |
| 480 | return status; | 487 | return status; |
| 481 | } | 488 | } |
| 482 | 489 | ||
| @@ -522,7 +529,7 @@ static int _nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs | |||
| 522 | memcpy(opendata->o_arg.u.delegation.data, state->stateid.data, | 529 | memcpy(opendata->o_arg.u.delegation.data, state->stateid.data, |
| 523 | sizeof(opendata->o_arg.u.delegation.data)); | 530 | sizeof(opendata->o_arg.u.delegation.data)); |
| 524 | ret = nfs4_open_recover(opendata, state); | 531 | ret = nfs4_open_recover(opendata, state); |
| 525 | nfs4_opendata_free(opendata); | 532 | nfs4_opendata_put(opendata); |
| 526 | return ret; | 533 | return ret; |
| 527 | } | 534 | } |
| 528 | 535 | ||
| @@ -593,7 +600,7 @@ static void nfs4_open_confirm_release(void *calldata) | |||
| 593 | if (state != NULL) | 600 | if (state != NULL) |
| 594 | nfs4_close_state(&data->path, state, data->o_arg.open_flags); | 601 | nfs4_close_state(&data->path, state, data->o_arg.open_flags); |
| 595 | out_free: | 602 | out_free: |
| 596 | nfs4_opendata_free(data); | 603 | nfs4_opendata_put(data); |
| 597 | } | 604 | } |
| 598 | 605 | ||
| 599 | static const struct rpc_call_ops nfs4_open_confirm_ops = { | 606 | static const struct rpc_call_ops nfs4_open_confirm_ops = { |
| @@ -611,7 +618,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data) | |||
| 611 | struct rpc_task *task; | 618 | struct rpc_task *task; |
| 612 | int status; | 619 | int status; |
| 613 | 620 | ||
| 614 | atomic_inc(&data->count); | 621 | kref_get(&data->kref); |
| 615 | /* | 622 | /* |
| 616 | * If rpc_run_task() ends up calling ->rpc_release(), we | 623 | * If rpc_run_task() ends up calling ->rpc_release(), we |
| 617 | * want to ensure that it takes the 'error' code path. | 624 | * want to ensure that it takes the 'error' code path. |
| @@ -696,7 +703,7 @@ static void nfs4_open_release(void *calldata) | |||
| 696 | if (state != NULL) | 703 | if (state != NULL) |
| 697 | nfs4_close_state(&data->path, state, data->o_arg.open_flags); | 704 | nfs4_close_state(&data->path, state, data->o_arg.open_flags); |
| 698 | out_free: | 705 | out_free: |
| 699 | nfs4_opendata_free(data); | 706 | nfs4_opendata_put(data); |
| 700 | } | 707 | } |
| 701 | 708 | ||
| 702 | static const struct rpc_call_ops nfs4_open_ops = { | 709 | static const struct rpc_call_ops nfs4_open_ops = { |
| @@ -717,7 +724,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) | |||
| 717 | struct rpc_task *task; | 724 | struct rpc_task *task; |
| 718 | int status; | 725 | int status; |
| 719 | 726 | ||
| 720 | atomic_inc(&data->count); | 727 | kref_get(&data->kref); |
| 721 | /* | 728 | /* |
| 722 | * If rpc_run_task() ends up calling ->rpc_release(), we | 729 | * If rpc_run_task() ends up calling ->rpc_release(), we |
| 723 | * want to ensure that it takes the 'error' code path. | 730 | * want to ensure that it takes the 'error' code path. |
| @@ -826,7 +833,7 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s | |||
| 826 | nfs4_drop_state_owner(state->owner); | 833 | nfs4_drop_state_owner(state->owner); |
| 827 | d_drop(ctx->path.dentry); | 834 | d_drop(ctx->path.dentry); |
| 828 | } | 835 | } |
| 829 | nfs4_opendata_free(opendata); | 836 | nfs4_opendata_put(opendata); |
| 830 | return ret; | 837 | return ret; |
| 831 | } | 838 | } |
| 832 | 839 | ||
| @@ -987,7 +994,7 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct | |||
| 987 | 994 | ||
| 988 | status = _nfs4_proc_open(opendata); | 995 | status = _nfs4_proc_open(opendata); |
| 989 | if (status != 0) | 996 | if (status != 0) |
| 990 | goto err_opendata_free; | 997 | goto err_opendata_put; |
| 991 | 998 | ||
| 992 | if (opendata->o_arg.open_flags & O_EXCL) | 999 | if (opendata->o_arg.open_flags & O_EXCL) |
| 993 | nfs4_exclusive_attrset(opendata, sattr); | 1000 | nfs4_exclusive_attrset(opendata, sattr); |
| @@ -995,16 +1002,16 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct | |||
| 995 | status = -ENOMEM; | 1002 | status = -ENOMEM; |
| 996 | state = nfs4_opendata_to_nfs4_state(opendata); | 1003 | state = nfs4_opendata_to_nfs4_state(opendata); |
| 997 | if (state == NULL) | 1004 | if (state == NULL) |
| 998 | goto err_opendata_free; | 1005 | goto err_opendata_put; |
| 999 | if (opendata->o_res.delegation_type != 0) | 1006 | if (opendata->o_res.delegation_type != 0) |
| 1000 | nfs_inode_set_delegation(state->inode, cred, &opendata->o_res); | 1007 | nfs_inode_set_delegation(state->inode, cred, &opendata->o_res); |
| 1001 | nfs4_opendata_free(opendata); | 1008 | nfs4_opendata_put(opendata); |
| 1002 | nfs4_put_state_owner(sp); | 1009 | nfs4_put_state_owner(sp); |
| 1003 | up_read(&clp->cl_sem); | 1010 | up_read(&clp->cl_sem); |
| 1004 | *res = state; | 1011 | *res = state; |
| 1005 | return 0; | 1012 | return 0; |
| 1006 | err_opendata_free: | 1013 | err_opendata_put: |
| 1007 | nfs4_opendata_free(opendata); | 1014 | nfs4_opendata_put(opendata); |
| 1008 | err_release_rwsem: | 1015 | err_release_rwsem: |
| 1009 | up_read(&clp->cl_sem); | 1016 | up_read(&clp->cl_sem); |
| 1010 | err_put_state_owner: | 1017 | err_put_state_owner: |
