|
35 | 35 | (1 + 3) * 4) // seqid, 3 slotids
|
36 | 36 | #define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
|
37 | 37 | #define CB_OP_RECALLSLOT_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
|
| 38 | +#define CB_OP_NOTIFY_LOCK_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) |
38 | 39 | #endif /* CONFIG_NFS_V4_1 */
|
39 | 40 |
|
40 | 41 | #define NFSDBG_FACILITY NFSDBG_CALLBACK
|
@@ -534,6 +535,49 @@ static __be32 decode_recallslot_args(struct svc_rqst *rqstp,
|
534 | 535 | return 0;
|
535 | 536 | }
|
536 | 537 |
|
| 538 | +static __be32 decode_lockowner(struct xdr_stream *xdr, struct cb_notify_lock_args *args) |
| 539 | +{ |
| 540 | + __be32 *p; |
| 541 | + unsigned int len; |
| 542 | + |
| 543 | + p = read_buf(xdr, 12); |
| 544 | + if (unlikely(p == NULL)) |
| 545 | + return htonl(NFS4ERR_BADXDR); |
| 546 | + |
| 547 | + p = xdr_decode_hyper(p, &args->cbnl_owner.clientid); |
| 548 | + len = be32_to_cpu(*p); |
| 549 | + |
| 550 | + p = read_buf(xdr, len); |
| 551 | + if (unlikely(p == NULL)) |
| 552 | + return htonl(NFS4ERR_BADXDR); |
| 553 | + |
| 554 | + /* Only try to decode if the length is right */ |
| 555 | + if (len == 20) { |
| 556 | + p += 2; /* skip "lock id:" */ |
| 557 | + args->cbnl_owner.s_dev = be32_to_cpu(*p++); |
| 558 | + xdr_decode_hyper(p, &args->cbnl_owner.id); |
| 559 | + args->cbnl_valid = true; |
| 560 | + } else { |
| 561 | + args->cbnl_owner.s_dev = 0; |
| 562 | + args->cbnl_owner.id = 0; |
| 563 | + args->cbnl_valid = false; |
| 564 | + } |
| 565 | + return 0; |
| 566 | +} |
| 567 | + |
| 568 | +static __be32 decode_notify_lock_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_notify_lock_args *args) |
| 569 | +{ |
| 570 | + __be32 status; |
| 571 | + |
| 572 | + status = decode_fh(xdr, &args->cbnl_fh); |
| 573 | + if (unlikely(status != 0)) |
| 574 | + goto out; |
| 575 | + status = decode_lockowner(xdr, args); |
| 576 | +out: |
| 577 | + dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); |
| 578 | + return status; |
| 579 | +} |
| 580 | + |
537 | 581 | #endif /* CONFIG_NFS_V4_1 */
|
538 | 582 |
|
539 | 583 | static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
|
@@ -746,14 +790,14 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
|
746 | 790 | case OP_CB_RECALL_SLOT:
|
747 | 791 | case OP_CB_LAYOUTRECALL:
|
748 | 792 | case OP_CB_NOTIFY_DEVICEID:
|
| 793 | + case OP_CB_NOTIFY_LOCK: |
749 | 794 | *op = &callback_ops[op_nr];
|
750 | 795 | break;
|
751 | 796 |
|
752 | 797 | case OP_CB_NOTIFY:
|
753 | 798 | case OP_CB_PUSH_DELEG:
|
754 | 799 | case OP_CB_RECALLABLE_OBJ_AVAIL:
|
755 | 800 | case OP_CB_WANTS_CANCELLED:
|
756 |
| - case OP_CB_NOTIFY_LOCK: |
757 | 801 | return htonl(NFS4ERR_NOTSUPP);
|
758 | 802 |
|
759 | 803 | default:
|
@@ -1006,6 +1050,11 @@ static struct callback_op callback_ops[] = {
|
1006 | 1050 | .decode_args = (callback_decode_arg_t)decode_recallslot_args,
|
1007 | 1051 | .res_maxsize = CB_OP_RECALLSLOT_RES_MAXSZ,
|
1008 | 1052 | },
|
| 1053 | + [OP_CB_NOTIFY_LOCK] = { |
| 1054 | + .process_op = (callback_process_op_t)nfs4_callback_notify_lock, |
| 1055 | + .decode_args = (callback_decode_arg_t)decode_notify_lock_args, |
| 1056 | + .res_maxsize = CB_OP_NOTIFY_LOCK_RES_MAXSZ, |
| 1057 | + }, |
1009 | 1058 | #endif /* CONFIG_NFS_V4_1 */
|
1010 | 1059 | };
|
1011 | 1060 |
|
|
0 commit comments