aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4callback.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4callback.c')
-rw-r--r--fs/nfsd/nfs4callback.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 7cbdf1b2e4ab..58277859a467 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -546,6 +546,102 @@ out:
546 return status; 546 return status;
547} 547}
548 548
549#ifdef CONFIG_NFSD_PNFS
550/*
551 * CB_LAYOUTRECALL4args
552 *
553 * struct layoutrecall_file4 {
554 * nfs_fh4 lor_fh;
555 * offset4 lor_offset;
556 * length4 lor_length;
557 * stateid4 lor_stateid;
558 * };
559 *
560 * union layoutrecall4 switch(layoutrecall_type4 lor_recalltype) {
561 * case LAYOUTRECALL4_FILE:
562 * layoutrecall_file4 lor_layout;
563 * case LAYOUTRECALL4_FSID:
564 * fsid4 lor_fsid;
565 * case LAYOUTRECALL4_ALL:
566 * void;
567 * };
568 *
569 * struct CB_LAYOUTRECALL4args {
570 * layouttype4 clora_type;
571 * layoutiomode4 clora_iomode;
572 * bool clora_changed;
573 * layoutrecall4 clora_recall;
574 * };
575 */
576static void encode_cb_layout4args(struct xdr_stream *xdr,
577 const struct nfs4_layout_stateid *ls,
578 struct nfs4_cb_compound_hdr *hdr)
579{
580 __be32 *p;
581
582 BUG_ON(hdr->minorversion == 0);
583
584 p = xdr_reserve_space(xdr, 5 * 4);
585 *p++ = cpu_to_be32(OP_CB_LAYOUTRECALL);
586 *p++ = cpu_to_be32(ls->ls_layout_type);
587 *p++ = cpu_to_be32(IOMODE_ANY);
588 *p++ = cpu_to_be32(1);
589 *p = cpu_to_be32(RETURN_FILE);
590
591 encode_nfs_fh4(xdr, &ls->ls_stid.sc_file->fi_fhandle);
592
593 p = xdr_reserve_space(xdr, 2 * 8);
594 p = xdr_encode_hyper(p, 0);
595 xdr_encode_hyper(p, NFS4_MAX_UINT64);
596
597 encode_stateid4(xdr, &ls->ls_recall_sid);
598
599 hdr->nops++;
600}
601
602static void nfs4_xdr_enc_cb_layout(struct rpc_rqst *req,
603 struct xdr_stream *xdr,
604 const struct nfsd4_callback *cb)
605{
606 const struct nfs4_layout_stateid *ls =
607 container_of(cb, struct nfs4_layout_stateid, ls_recall);
608 struct nfs4_cb_compound_hdr hdr = {
609 .ident = 0,
610 .minorversion = cb->cb_minorversion,
611 };
612
613 encode_cb_compound4args(xdr, &hdr);
614 encode_cb_sequence4args(xdr, cb, &hdr);
615 encode_cb_layout4args(xdr, ls, &hdr);
616 encode_cb_nops(&hdr);
617}
618
619static int nfs4_xdr_dec_cb_layout(struct rpc_rqst *rqstp,
620 struct xdr_stream *xdr,
621 struct nfsd4_callback *cb)
622{
623 struct nfs4_cb_compound_hdr hdr;
624 enum nfsstat4 nfserr;
625 int status;
626
627 status = decode_cb_compound4res(xdr, &hdr);
628 if (unlikely(status))
629 goto out;
630 if (cb) {
631 status = decode_cb_sequence4res(xdr, cb);
632 if (unlikely(status))
633 goto out;
634 }
635 status = decode_cb_op_status(xdr, OP_CB_LAYOUTRECALL, &nfserr);
636 if (unlikely(status))
637 goto out;
638 if (unlikely(nfserr != NFS4_OK))
639 status = nfs_cb_stat_to_errno(nfserr);
640out:
641 return status;
642}
643#endif /* CONFIG_NFSD_PNFS */
644
549/* 645/*
550 * RPC procedure tables 646 * RPC procedure tables
551 */ 647 */
@@ -563,6 +659,9 @@ out:
563static struct rpc_procinfo nfs4_cb_procedures[] = { 659static struct rpc_procinfo nfs4_cb_procedures[] = {
564 PROC(CB_NULL, NULL, cb_null, cb_null), 660 PROC(CB_NULL, NULL, cb_null, cb_null),
565 PROC(CB_RECALL, COMPOUND, cb_recall, cb_recall), 661 PROC(CB_RECALL, COMPOUND, cb_recall, cb_recall),
662#ifdef CONFIG_NFSD_PNFS
663 PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout),
664#endif
566}; 665};
567 666
568static struct rpc_version nfs_cb_version4 = { 667static struct rpc_version nfs_cb_version4 = {