diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 69 |
1 files changed, 32 insertions, 37 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 612a9a14aed3..35da15342e05 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2889,11 +2889,23 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r | |||
2889 | struct inode *inode = state->inode; | 2889 | struct inode *inode = state->inode; |
2890 | struct nfs_server *server = NFS_SERVER(inode); | 2890 | struct nfs_server *server = NFS_SERVER(inode); |
2891 | struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner; | 2891 | struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner; |
2892 | struct nfs_lock_opargs largs = { | ||
2893 | .lock_stateid = &lsp->ls_stateid, | ||
2894 | .open_stateid = &state->stateid, | ||
2895 | .lock_owner = { | ||
2896 | .clientid = server->nfs4_state->cl_clientid, | ||
2897 | .id = lsp->ls_id, | ||
2898 | }, | ||
2899 | .reclaim = reclaim, | ||
2900 | }; | ||
2892 | struct nfs_lockargs arg = { | 2901 | struct nfs_lockargs arg = { |
2893 | .fh = NFS_FH(inode), | 2902 | .fh = NFS_FH(inode), |
2894 | .type = nfs4_lck_type(cmd, request), | 2903 | .type = nfs4_lck_type(cmd, request), |
2895 | .offset = request->fl_start, | 2904 | .offset = request->fl_start, |
2896 | .length = nfs4_lck_length(request), | 2905 | .length = nfs4_lck_length(request), |
2906 | .u = { | ||
2907 | .lock = &largs, | ||
2908 | }, | ||
2897 | }; | 2909 | }; |
2898 | struct nfs_lockres res = { | 2910 | struct nfs_lockres res = { |
2899 | .server = server, | 2911 | .server = server, |
@@ -2904,56 +2916,39 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r | |||
2904 | .rpc_resp = &res, | 2916 | .rpc_resp = &res, |
2905 | .rpc_cred = state->owner->so_cred, | 2917 | .rpc_cred = state->owner->so_cred, |
2906 | }; | 2918 | }; |
2907 | struct nfs_lock_opargs largs = { | ||
2908 | .reclaim = reclaim, | ||
2909 | .new_lock_owner = 0, | ||
2910 | }; | ||
2911 | struct nfs_seqid *lock_seqid; | ||
2912 | int status = -ENOMEM; | 2919 | int status = -ENOMEM; |
2913 | 2920 | ||
2914 | lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid); | 2921 | largs.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid); |
2915 | if (lock_seqid == NULL) | 2922 | if (largs.lock_seqid == NULL) |
2916 | return -ENOMEM; | 2923 | return -ENOMEM; |
2917 | if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) { | 2924 | if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) { |
2918 | struct nfs4_state_owner *owner = state->owner; | 2925 | struct nfs4_state_owner *owner = state->owner; |
2919 | struct nfs_open_to_lock otl = { | 2926 | |
2920 | .lock_owner = { | 2927 | largs.open_seqid = nfs_alloc_seqid(&owner->so_seqid); |
2921 | .clientid = server->nfs4_state->cl_clientid, | 2928 | if (largs.open_seqid == NULL) |
2922 | }, | 2929 | goto out; |
2923 | }; | ||
2924 | |||
2925 | otl.lock_seqid = lock_seqid; | ||
2926 | otl.lock_owner.id = lsp->ls_id; | ||
2927 | memcpy(&otl.open_stateid, &state->stateid, sizeof(otl.open_stateid)); | ||
2928 | largs.u.open_lock = &otl; | ||
2929 | largs.new_lock_owner = 1; | 2930 | largs.new_lock_owner = 1; |
2930 | arg.u.lock = &largs; | 2931 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); |
2931 | otl.open_seqid = nfs_alloc_seqid(&owner->so_seqid); | 2932 | /* increment open seqid on success, and seqid mutating errors */ |
2932 | if (otl.open_seqid != NULL) { | 2933 | if (largs.new_lock_owner != 0) { |
2933 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); | 2934 | nfs_increment_open_seqid(status, largs.open_seqid); |
2934 | /* increment seqid on success, and seqid mutating errors */ | 2935 | if (status == 0) |
2935 | nfs_increment_open_seqid(status, otl.open_seqid); | 2936 | nfs_confirm_seqid(&lsp->ls_seqid, 0); |
2936 | nfs_free_seqid(otl.open_seqid); | ||
2937 | } | 2937 | } |
2938 | if (status == 0) | 2938 | nfs_free_seqid(largs.open_seqid); |
2939 | nfs_confirm_seqid(&lsp->ls_seqid, 0); | 2939 | } else |
2940 | } else { | ||
2941 | struct nfs_exist_lock el; | ||
2942 | memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid)); | ||
2943 | largs.u.exist_lock = ⪙ | ||
2944 | arg.u.lock = &largs; | ||
2945 | el.seqid = lock_seqid; | ||
2946 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); | 2940 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); |
2947 | } | 2941 | /* increment lock seqid on success, and seqid mutating errors*/ |
2948 | /* increment seqid on success, and seqid mutating errors*/ | 2942 | nfs_increment_lock_seqid(status, largs.lock_seqid); |
2949 | nfs_increment_lock_seqid(status, lock_seqid); | ||
2950 | /* save the returned stateid. */ | 2943 | /* save the returned stateid. */ |
2951 | if (status == 0) { | 2944 | if (status == 0) { |
2952 | memcpy(lsp->ls_stateid.data, res.u.stateid.data, sizeof(lsp->ls_stateid.data)); | 2945 | memcpy(lsp->ls_stateid.data, res.u.stateid.data, |
2946 | sizeof(lsp->ls_stateid.data)); | ||
2953 | lsp->ls_flags |= NFS_LOCK_INITIALIZED; | 2947 | lsp->ls_flags |= NFS_LOCK_INITIALIZED; |
2954 | } else if (status == -NFS4ERR_DENIED) | 2948 | } else if (status == -NFS4ERR_DENIED) |
2955 | status = -EAGAIN; | 2949 | status = -EAGAIN; |
2956 | nfs_free_seqid(lock_seqid); | 2950 | out: |
2951 | nfs_free_seqid(largs.lock_seqid); | ||
2957 | return status; | 2952 | return status; |
2958 | } | 2953 | } |
2959 | 2954 | ||