diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-06-22 13:16:32 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-06-22 16:07:42 -0400 |
commit | 8d0a8a9d0ec790086c64d210af413ac351d89e35 (patch) | |
tree | 003a1481e4a8d8487956a6bf04db80dd93264b8b /fs/nfs/nfs4proc.c | |
parent | ecdbf769b2cb8903e07cd482334c714d89fd1146 (diff) |
[PATCH] NFSv4: Clean up nfs4 lock state accounting
Ensure that lock owner structures are not released prematurely.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 69 |
1 files changed, 30 insertions, 39 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index af80b5981486..0ddc20102d46 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2626,14 +2626,11 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock | |||
2626 | down_read(&clp->cl_sem); | 2626 | down_read(&clp->cl_sem); |
2627 | nlo.clientid = clp->cl_clientid; | 2627 | nlo.clientid = clp->cl_clientid; |
2628 | down(&state->lock_sema); | 2628 | down(&state->lock_sema); |
2629 | lsp = nfs4_find_lock_state(state, request->fl_owner); | 2629 | status = nfs4_set_lock_state(state, request); |
2630 | if (lsp) | 2630 | if (status != 0) |
2631 | nlo.id = lsp->ls_id; | 2631 | goto out; |
2632 | else { | 2632 | lsp = request->fl_u.nfs4_fl.owner; |
2633 | spin_lock(&clp->cl_lock); | 2633 | nlo.id = lsp->ls_id; |
2634 | nlo.id = nfs4_alloc_lockowner_id(clp); | ||
2635 | spin_unlock(&clp->cl_lock); | ||
2636 | } | ||
2637 | arg.u.lockt = &nlo; | 2634 | arg.u.lockt = &nlo; |
2638 | status = rpc_call_sync(server->client, &msg, 0); | 2635 | status = rpc_call_sync(server->client, &msg, 0); |
2639 | if (!status) { | 2636 | if (!status) { |
@@ -2654,8 +2651,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock | |||
2654 | request->fl_pid = 0; | 2651 | request->fl_pid = 0; |
2655 | status = 0; | 2652 | status = 0; |
2656 | } | 2653 | } |
2657 | if (lsp) | 2654 | out: |
2658 | nfs4_put_lock_state(lsp); | ||
2659 | up(&state->lock_sema); | 2655 | up(&state->lock_sema); |
2660 | up_read(&clp->cl_sem); | 2656 | up_read(&clp->cl_sem); |
2661 | return status; | 2657 | return status; |
@@ -2715,28 +2711,26 @@ static int _nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock | |||
2715 | }; | 2711 | }; |
2716 | struct nfs4_lock_state *lsp; | 2712 | struct nfs4_lock_state *lsp; |
2717 | struct nfs_locku_opargs luargs; | 2713 | struct nfs_locku_opargs luargs; |
2718 | int status = 0; | 2714 | int status; |
2719 | 2715 | ||
2720 | down_read(&clp->cl_sem); | 2716 | down_read(&clp->cl_sem); |
2721 | down(&state->lock_sema); | 2717 | down(&state->lock_sema); |
2722 | lsp = nfs4_find_lock_state(state, request->fl_owner); | 2718 | status = nfs4_set_lock_state(state, request); |
2723 | if (!lsp) | 2719 | if (status != 0) |
2724 | goto out; | 2720 | goto out; |
2721 | lsp = request->fl_u.nfs4_fl.owner; | ||
2725 | /* We might have lost the locks! */ | 2722 | /* We might have lost the locks! */ |
2726 | if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) { | 2723 | if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) |
2727 | luargs.seqid = lsp->ls_seqid; | 2724 | goto out; |
2728 | memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid)); | 2725 | luargs.seqid = lsp->ls_seqid; |
2729 | arg.u.locku = &luargs; | 2726 | memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid)); |
2730 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); | 2727 | arg.u.locku = &luargs; |
2731 | nfs4_increment_lock_seqid(status, lsp); | 2728 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); |
2732 | } | 2729 | nfs4_increment_lock_seqid(status, lsp); |
2733 | 2730 | ||
2734 | if (status == 0) { | 2731 | if (status == 0) |
2735 | memcpy(&lsp->ls_stateid, &res.u.stateid, | 2732 | memcpy(&lsp->ls_stateid, &res.u.stateid, |
2736 | sizeof(lsp->ls_stateid)); | 2733 | sizeof(lsp->ls_stateid)); |
2737 | nfs4_notify_unlck(state, request, lsp); | ||
2738 | } | ||
2739 | nfs4_put_lock_state(lsp); | ||
2740 | out: | 2734 | out: |
2741 | up(&state->lock_sema); | 2735 | up(&state->lock_sema); |
2742 | if (status == 0) | 2736 | if (status == 0) |
@@ -2762,7 +2756,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r | |||
2762 | { | 2756 | { |
2763 | struct inode *inode = state->inode; | 2757 | struct inode *inode = state->inode; |
2764 | struct nfs_server *server = NFS_SERVER(inode); | 2758 | struct nfs_server *server = NFS_SERVER(inode); |
2765 | struct nfs4_lock_state *lsp; | 2759 | struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner; |
2766 | struct nfs_lockargs arg = { | 2760 | struct nfs_lockargs arg = { |
2767 | .fh = NFS_FH(inode), | 2761 | .fh = NFS_FH(inode), |
2768 | .type = nfs4_lck_type(cmd, request), | 2762 | .type = nfs4_lck_type(cmd, request), |
@@ -2784,9 +2778,6 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r | |||
2784 | }; | 2778 | }; |
2785 | int status; | 2779 | int status; |
2786 | 2780 | ||
2787 | lsp = nfs4_get_lock_state(state, request->fl_owner); | ||
2788 | if (lsp == NULL) | ||
2789 | return -ENOMEM; | ||
2790 | if (!(lsp->ls_flags & NFS_LOCK_INITIALIZED)) { | 2781 | if (!(lsp->ls_flags & NFS_LOCK_INITIALIZED)) { |
2791 | struct nfs4_state_owner *owner = state->owner; | 2782 | struct nfs4_state_owner *owner = state->owner; |
2792 | struct nfs_open_to_lock otl = { | 2783 | struct nfs_open_to_lock otl = { |
@@ -2808,27 +2799,26 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r | |||
2808 | * seqid mutating errors */ | 2799 | * seqid mutating errors */ |
2809 | nfs4_increment_seqid(status, owner); | 2800 | nfs4_increment_seqid(status, owner); |
2810 | up(&owner->so_sema); | 2801 | up(&owner->so_sema); |
2802 | if (status == 0) { | ||
2803 | lsp->ls_flags |= NFS_LOCK_INITIALIZED; | ||
2804 | lsp->ls_seqid++; | ||
2805 | } | ||
2811 | } else { | 2806 | } else { |
2812 | struct nfs_exist_lock el = { | 2807 | struct nfs_exist_lock el = { |
2813 | .seqid = lsp->ls_seqid, | 2808 | .seqid = lsp->ls_seqid, |
2814 | }; | 2809 | }; |
2815 | memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid)); | 2810 | memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid)); |
2816 | largs.u.exist_lock = ⪙ | 2811 | largs.u.exist_lock = ⪙ |
2817 | largs.new_lock_owner = 0; | ||
2818 | arg.u.lock = &largs; | 2812 | arg.u.lock = &largs; |
2819 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); | 2813 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); |
2814 | /* increment seqid on success, and * seqid mutating errors*/ | ||
2815 | nfs4_increment_lock_seqid(status, lsp); | ||
2820 | } | 2816 | } |
2821 | /* increment seqid on success, and * seqid mutating errors*/ | ||
2822 | nfs4_increment_lock_seqid(status, lsp); | ||
2823 | /* save the returned stateid. */ | 2817 | /* save the returned stateid. */ |
2824 | if (status == 0) { | 2818 | if (status == 0) |
2825 | memcpy(&lsp->ls_stateid, &res.u.stateid, sizeof(nfs4_stateid)); | 2819 | memcpy(&lsp->ls_stateid, &res.u.stateid, sizeof(nfs4_stateid)); |
2826 | lsp->ls_flags |= NFS_LOCK_INITIALIZED; | 2820 | else if (status == -NFS4ERR_DENIED) |
2827 | if (!reclaim) | ||
2828 | nfs4_notify_setlk(state, request, lsp); | ||
2829 | } else if (status == -NFS4ERR_DENIED) | ||
2830 | status = -EAGAIN; | 2821 | status = -EAGAIN; |
2831 | nfs4_put_lock_state(lsp); | ||
2832 | return status; | 2822 | return status; |
2833 | } | 2823 | } |
2834 | 2824 | ||
@@ -2869,7 +2859,9 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock | |||
2869 | 2859 | ||
2870 | down_read(&clp->cl_sem); | 2860 | down_read(&clp->cl_sem); |
2871 | down(&state->lock_sema); | 2861 | down(&state->lock_sema); |
2872 | status = _nfs4_do_setlk(state, cmd, request, 0); | 2862 | status = nfs4_set_lock_state(state, request); |
2863 | if (status == 0) | ||
2864 | status = _nfs4_do_setlk(state, cmd, request, 0); | ||
2873 | up(&state->lock_sema); | 2865 | up(&state->lock_sema); |
2874 | if (status == 0) { | 2866 | if (status == 0) { |
2875 | /* Note: we always want to sleep here! */ | 2867 | /* Note: we always want to sleep here! */ |
@@ -2927,7 +2919,6 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request) | |||
2927 | if (signalled()) | 2919 | if (signalled()) |
2928 | break; | 2920 | break; |
2929 | } while(status < 0); | 2921 | } while(status < 0); |
2930 | |||
2931 | return status; | 2922 | return status; |
2932 | } | 2923 | } |
2933 | 2924 | ||