diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-10-18 17:20:15 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-10-18 17:20:15 -0400 |
commit | 06735b3454824bd561decbde46111f144e905923 (patch) | |
tree | 2c9e9f18ba8d3700a181b44d2b1f0ce6a62612f8 /fs/nfs | |
parent | faf5f49c2d9c0af2847837c232a432cc146e203b (diff) |
NFSv4: Fix up handling of open_to_lock sequence ids
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 69 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 32 |
2 files changed, 45 insertions, 56 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 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 4706192cfb07..c5c75235c5b8 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -729,22 +729,18 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg) | |||
729 | WRITE64(arg->length); | 729 | WRITE64(arg->length); |
730 | WRITE32(opargs->new_lock_owner); | 730 | WRITE32(opargs->new_lock_owner); |
731 | if (opargs->new_lock_owner){ | 731 | if (opargs->new_lock_owner){ |
732 | struct nfs_open_to_lock *ol = opargs->u.open_lock; | ||
733 | |||
734 | RESERVE_SPACE(40); | 732 | RESERVE_SPACE(40); |
735 | WRITE32(ol->open_seqid->sequence->counter); | 733 | WRITE32(opargs->open_seqid->sequence->counter); |
736 | WRITEMEM(&ol->open_stateid, sizeof(ol->open_stateid)); | 734 | WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data)); |
737 | WRITE32(ol->lock_seqid->sequence->counter); | 735 | WRITE32(opargs->lock_seqid->sequence->counter); |
738 | WRITE64(ol->lock_owner.clientid); | 736 | WRITE64(opargs->lock_owner.clientid); |
739 | WRITE32(4); | 737 | WRITE32(4); |
740 | WRITE32(ol->lock_owner.id); | 738 | WRITE32(opargs->lock_owner.id); |
741 | } | 739 | } |
742 | else { | 740 | else { |
743 | struct nfs_exist_lock *el = opargs->u.exist_lock; | ||
744 | |||
745 | RESERVE_SPACE(20); | 741 | RESERVE_SPACE(20); |
746 | WRITEMEM(&el->stateid, sizeof(el->stateid)); | 742 | WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data)); |
747 | WRITE32(el->seqid->sequence->counter); | 743 | WRITE32(opargs->lock_seqid->sequence->counter); |
748 | } | 744 | } |
749 | 745 | ||
750 | return 0; | 746 | return 0; |
@@ -1535,16 +1531,14 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_locka | |||
1535 | .nops = 2, | 1531 | .nops = 2, |
1536 | }; | 1532 | }; |
1537 | struct nfs_lock_opargs *opargs = args->u.lock; | 1533 | struct nfs_lock_opargs *opargs = args->u.lock; |
1538 | struct nfs_seqid *seqid; | ||
1539 | int status; | 1534 | int status; |
1540 | 1535 | ||
1541 | if (opargs->new_lock_owner) | 1536 | status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task); |
1542 | seqid = opargs->u.open_lock->lock_seqid; | ||
1543 | else | ||
1544 | seqid = opargs->u.exist_lock->seqid; | ||
1545 | status = nfs_wait_on_sequence(seqid, req->rq_task); | ||
1546 | if (status != 0) | 1537 | if (status != 0) |
1547 | goto out; | 1538 | goto out; |
1539 | /* Do we need to do an open_to_lock_owner? */ | ||
1540 | if (opargs->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED) | ||
1541 | opargs->new_lock_owner = 0; | ||
1548 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1542 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
1549 | encode_compound_hdr(&xdr, &hdr); | 1543 | encode_compound_hdr(&xdr, &hdr); |
1550 | status = encode_putfh(&xdr, args->fh); | 1544 | status = encode_putfh(&xdr, args->fh); |
@@ -2908,8 +2902,8 @@ static int decode_lock(struct xdr_stream *xdr, struct nfs_lockres *res) | |||
2908 | 2902 | ||
2909 | status = decode_op_hdr(xdr, OP_LOCK); | 2903 | status = decode_op_hdr(xdr, OP_LOCK); |
2910 | if (status == 0) { | 2904 | if (status == 0) { |
2911 | READ_BUF(sizeof(nfs4_stateid)); | 2905 | READ_BUF(sizeof(res->u.stateid.data)); |
2912 | COPYMEM(&res->u.stateid, sizeof(res->u.stateid)); | 2906 | COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data)); |
2913 | } else if (status == -NFS4ERR_DENIED) | 2907 | } else if (status == -NFS4ERR_DENIED) |
2914 | return decode_lock_denied(xdr, &res->u.denied); | 2908 | return decode_lock_denied(xdr, &res->u.denied); |
2915 | return status; | 2909 | return status; |