aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2016-09-16 16:28:23 -0400
committerJ. Bruce Fields <bfields@redhat.com>2016-09-26 15:20:35 -0400
commita188620ebd294b18d8da93f4b2a307d484e7bd27 (patch)
tree9c59983232415a6c55452569422d64402f22d687
parent1eca45f8a840987d0df355e0176921653e4f7ec2 (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.c57
-rw-r--r--fs/nfsd/state.h7
-rw-r--r--fs/nfsd/xdr4cb.h9
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
626static 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
635static 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
663static 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
648static struct rpc_version nfs_cb_version4 = { 705static 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
583struct nfsd4_blocked_lock {
584 struct file_lock nbl_lock;
585 struct knfsd_fh nbl_fh;
586 struct nfsd4_callback nbl_cb;
587};
588
582struct nfsd4_compound_state; 589struct nfsd4_compound_state;
583struct nfsd_net; 590struct 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)