diff options
author | Jeff Layton <jlayton@redhat.com> | 2016-09-16 16:28:23 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2016-09-26 15:20:35 -0400 |
commit | a188620ebd294b18d8da93f4b2a307d484e7bd27 (patch) | |
tree | 9c59983232415a6c55452569422d64402f22d687 | |
parent | 1eca45f8a840987d0df355e0176921653e4f7ec2 (diff) |
nfsd: plumb in a CB_NOTIFY_LOCK operation
Add the encoding/decoding for CB_NOTIFY_LOCK operations.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r-- | fs/nfsd/nfs4callback.c | 57 | ||||
-rw-r--r-- | fs/nfsd/state.h | 7 | ||||
-rw-r--r-- | fs/nfsd/xdr4cb.h | 9 |
3 files changed, 73 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index dbef646c6a2d..211dc2aed8e1 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -623,6 +623,62 @@ static int nfs4_xdr_dec_cb_layout(struct rpc_rqst *rqstp, | |||
623 | } | 623 | } |
624 | #endif /* CONFIG_NFSD_PNFS */ | 624 | #endif /* CONFIG_NFSD_PNFS */ |
625 | 625 | ||
626 | static void encode_stateowner(struct xdr_stream *xdr, struct nfs4_stateowner *so) | ||
627 | { | ||
628 | __be32 *p; | ||
629 | |||
630 | p = xdr_reserve_space(xdr, 8 + 4 + so->so_owner.len); | ||
631 | p = xdr_encode_opaque_fixed(p, &so->so_client->cl_clientid, 8); | ||
632 | xdr_encode_opaque(p, so->so_owner.data, so->so_owner.len); | ||
633 | } | ||
634 | |||
635 | static void nfs4_xdr_enc_cb_notify_lock(struct rpc_rqst *req, | ||
636 | struct xdr_stream *xdr, | ||
637 | const struct nfsd4_callback *cb) | ||
638 | { | ||
639 | const struct nfsd4_blocked_lock *nbl = | ||
640 | container_of(cb, struct nfsd4_blocked_lock, nbl_cb); | ||
641 | struct nfs4_lockowner *lo = (struct nfs4_lockowner *)nbl->nbl_lock.fl_owner; | ||
642 | struct nfs4_cb_compound_hdr hdr = { | ||
643 | .ident = 0, | ||
644 | .minorversion = cb->cb_clp->cl_minorversion, | ||
645 | }; | ||
646 | |||
647 | __be32 *p; | ||
648 | |||
649 | BUG_ON(hdr.minorversion == 0); | ||
650 | |||
651 | encode_cb_compound4args(xdr, &hdr); | ||
652 | encode_cb_sequence4args(xdr, cb, &hdr); | ||
653 | |||
654 | p = xdr_reserve_space(xdr, 4); | ||
655 | *p = cpu_to_be32(OP_CB_NOTIFY_LOCK); | ||
656 | encode_nfs_fh4(xdr, &nbl->nbl_fh); | ||
657 | encode_stateowner(xdr, &lo->lo_owner); | ||
658 | hdr.nops++; | ||
659 | |||
660 | encode_cb_nops(&hdr); | ||
661 | } | ||
662 | |||
663 | static int nfs4_xdr_dec_cb_notify_lock(struct rpc_rqst *rqstp, | ||
664 | struct xdr_stream *xdr, | ||
665 | struct nfsd4_callback *cb) | ||
666 | { | ||
667 | struct nfs4_cb_compound_hdr hdr; | ||
668 | int status; | ||
669 | |||
670 | status = decode_cb_compound4res(xdr, &hdr); | ||
671 | if (unlikely(status)) | ||
672 | return status; | ||
673 | |||
674 | if (cb) { | ||
675 | status = decode_cb_sequence4res(xdr, cb); | ||
676 | if (unlikely(status || cb->cb_seq_status)) | ||
677 | return status; | ||
678 | } | ||
679 | return decode_cb_op_status(xdr, OP_CB_NOTIFY_LOCK, &cb->cb_status); | ||
680 | } | ||
681 | |||
626 | /* | 682 | /* |
627 | * RPC procedure tables | 683 | * RPC procedure tables |
628 | */ | 684 | */ |
@@ -643,6 +699,7 @@ static struct rpc_procinfo nfs4_cb_procedures[] = { | |||
643 | #ifdef CONFIG_NFSD_PNFS | 699 | #ifdef CONFIG_NFSD_PNFS |
644 | PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout), | 700 | PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout), |
645 | #endif | 701 | #endif |
702 | PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock), | ||
646 | }; | 703 | }; |
647 | 704 | ||
648 | static struct rpc_version nfs_cb_version4 = { | 705 | static struct rpc_version nfs_cb_version4 = { |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 0bdc79cb359c..88d029dd13aa 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -571,6 +571,7 @@ enum nfsd4_cb_op { | |||
571 | NFSPROC4_CLNT_CB_RECALL, | 571 | NFSPROC4_CLNT_CB_RECALL, |
572 | NFSPROC4_CLNT_CB_LAYOUT, | 572 | NFSPROC4_CLNT_CB_LAYOUT, |
573 | NFSPROC4_CLNT_CB_SEQUENCE, | 573 | NFSPROC4_CLNT_CB_SEQUENCE, |
574 | NFSPROC4_CLNT_CB_NOTIFY_LOCK, | ||
574 | }; | 575 | }; |
575 | 576 | ||
576 | /* Returns true iff a is later than b: */ | 577 | /* Returns true iff a is later than b: */ |
@@ -579,6 +580,12 @@ static inline bool nfsd4_stateid_generation_after(stateid_t *a, stateid_t *b) | |||
579 | return (s32)(a->si_generation - b->si_generation) > 0; | 580 | return (s32)(a->si_generation - b->si_generation) > 0; |
580 | } | 581 | } |
581 | 582 | ||
583 | struct nfsd4_blocked_lock { | ||
584 | struct file_lock nbl_lock; | ||
585 | struct knfsd_fh nbl_fh; | ||
586 | struct nfsd4_callback nbl_cb; | ||
587 | }; | ||
588 | |||
582 | struct nfsd4_compound_state; | 589 | struct nfsd4_compound_state; |
583 | struct nfsd_net; | 590 | struct nfsd_net; |
584 | 591 | ||
diff --git a/fs/nfsd/xdr4cb.h b/fs/nfsd/xdr4cb.h index c47f6fdb111a..49b719dfef95 100644 --- a/fs/nfsd/xdr4cb.h +++ b/fs/nfsd/xdr4cb.h | |||
@@ -28,3 +28,12 @@ | |||
28 | #define NFS4_dec_cb_layout_sz (cb_compound_dec_hdr_sz + \ | 28 | #define NFS4_dec_cb_layout_sz (cb_compound_dec_hdr_sz + \ |
29 | cb_sequence_dec_sz + \ | 29 | cb_sequence_dec_sz + \ |
30 | op_dec_sz) | 30 | op_dec_sz) |
31 | |||
32 | #define NFS4_enc_cb_notify_lock_sz (cb_compound_enc_hdr_sz + \ | ||
33 | cb_sequence_enc_sz + \ | ||
34 | 2 + 1 + \ | ||
35 | XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \ | ||
36 | enc_nfs4_fh_sz) | ||
37 | #define NFS4_dec_cb_notify_lock_sz (cb_compound_dec_hdr_sz + \ | ||
38 | cb_sequence_dec_sz + \ | ||
39 | op_dec_sz) | ||