aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4proc.c69
-rw-r--r--fs/nfs/nfs4xdr.c32
-rw-r--r--include/linux/nfs_xdr.h19
3 files changed, 49 insertions, 71 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); 2950out:
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;
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 849f95c5fae4..57efcc27f20b 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -165,25 +165,14 @@ struct nfs_lowner {
165 u32 id; 165 u32 id;
166}; 166};
167 167
168struct nfs_open_to_lock { 168struct nfs_lock_opargs {
169 struct nfs_seqid * open_seqid;
170 nfs4_stateid open_stateid;
171 struct nfs_seqid * lock_seqid; 169 struct nfs_seqid * lock_seqid;
170 nfs4_stateid * lock_stateid;
171 struct nfs_seqid * open_seqid;
172 nfs4_stateid * open_stateid;
172 struct nfs_lowner lock_owner; 173 struct nfs_lowner lock_owner;
173};
174
175struct nfs_exist_lock {
176 nfs4_stateid stateid;
177 struct nfs_seqid * seqid;
178};
179
180struct nfs_lock_opargs {
181 __u32 reclaim; 174 __u32 reclaim;
182 __u32 new_lock_owner; 175 __u32 new_lock_owner;
183 union {
184 struct nfs_open_to_lock *open_lock;
185 struct nfs_exist_lock *exist_lock;
186 } u;
187}; 176};
188 177
189struct nfs_locku_opargs { 178struct nfs_locku_opargs {