Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFSD CB_OFFLOAD xdr

Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>

authored by

Olga Kornievskaia and committed by
J. Bruce Fields
9eb190fc 6bf4ca7f

+115
+98
fs/nfsd/nfs4callback.c
··· 39 39 #include "state.h" 40 40 #include "netns.h" 41 41 #include "xdr4cb.h" 42 + #include "xdr4.h" 42 43 43 44 #define NFSDDBG_FACILITY NFSDDBG_PROC 44 45 ··· 106 105 OP_CB_WANTS_CANCELLED = 12, 107 106 OP_CB_NOTIFY_LOCK = 13, 108 107 OP_CB_NOTIFY_DEVICEID = 14, 108 + OP_CB_OFFLOAD = 15, 109 109 OP_CB_ILLEGAL = 10044 110 110 }; 111 111 ··· 685 683 } 686 684 687 685 /* 686 + * struct write_response4 { 687 + * stateid4 wr_callback_id<1>; 688 + * length4 wr_count; 689 + * stable_how4 wr_committed; 690 + * verifier4 wr_writeverf; 691 + * }; 692 + * union offload_info4 switch (nfsstat4 coa_status) { 693 + * case NFS4_OK: 694 + * write_response4 coa_resok4; 695 + * default: 696 + * length4 coa_bytes_copied; 697 + * }; 698 + * struct CB_OFFLOAD4args { 699 + * nfs_fh4 coa_fh; 700 + * stateid4 coa_stateid; 701 + * offload_info4 coa_offload_info; 702 + * }; 703 + */ 704 + static void encode_offload_info4(struct xdr_stream *xdr, 705 + __be32 nfserr, 706 + const struct nfsd4_copy *cp) 707 + { 708 + __be32 *p; 709 + 710 + p = xdr_reserve_space(xdr, 4); 711 + *p++ = nfserr; 712 + if (!nfserr) { 713 + p = xdr_reserve_space(xdr, 4 + 8 + 4 + NFS4_VERIFIER_SIZE); 714 + p = xdr_encode_empty_array(p); 715 + p = xdr_encode_hyper(p, cp->cp_res.wr_bytes_written); 716 + *p++ = cpu_to_be32(cp->cp_res.wr_stable_how); 717 + p = xdr_encode_opaque_fixed(p, cp->cp_res.wr_verifier.data, 718 + NFS4_VERIFIER_SIZE); 719 + } else { 720 + p = xdr_reserve_space(xdr, 8); 721 + /* We always return success if bytes were written */ 722 + p = xdr_encode_hyper(p, 0); 723 + } 724 + } 725 + 726 + static void encode_cb_offload4args(struct xdr_stream *xdr, 727 + __be32 nfserr, 728 + const struct knfsd_fh *fh, 729 + const struct nfsd4_copy *cp, 730 + struct nfs4_cb_compound_hdr *hdr) 731 + { 732 + __be32 *p; 733 + 734 + p = xdr_reserve_space(xdr, 4); 735 + *p++ = cpu_to_be32(OP_CB_OFFLOAD); 736 + encode_nfs_fh4(xdr, fh); 737 + encode_stateid4(xdr, &cp->cp_res.cb_stateid); 738 + encode_offload_info4(xdr, nfserr, cp); 739 + 740 + hdr->nops++; 741 + } 742 + 743 + static void nfs4_xdr_enc_cb_offload(struct rpc_rqst *req, 744 + struct xdr_stream *xdr, 745 + const void *data) 746 + { 747 + const struct nfsd4_callback *cb = data; 748 + const struct nfsd4_copy *cp = 749 + container_of(cb, struct nfsd4_copy, cp_cb); 750 + struct nfs4_cb_compound_hdr hdr = { 751 + .ident = 0, 752 + .minorversion = cb->cb_clp->cl_minorversion, 753 + }; 754 + 755 + encode_cb_compound4args(xdr, &hdr); 756 + encode_cb_sequence4args(xdr, cb, &hdr); 757 + encode_cb_offload4args(xdr, cp->nfserr, &cp->fh, cp, &hdr); 758 + encode_cb_nops(&hdr); 759 + } 760 + 761 + static int nfs4_xdr_dec_cb_offload(struct rpc_rqst *rqstp, 762 + struct xdr_stream *xdr, 763 + void *data) 764 + { 765 + struct nfsd4_callback *cb = data; 766 + struct nfs4_cb_compound_hdr hdr; 767 + int status; 768 + 769 + status = decode_cb_compound4res(xdr, &hdr); 770 + if (unlikely(status)) 771 + return status; 772 + 773 + if (cb) { 774 + status = decode_cb_sequence4res(xdr, cb); 775 + if (unlikely(status || cb->cb_seq_status)) 776 + return status; 777 + } 778 + return decode_cb_op_status(xdr, OP_CB_OFFLOAD, &cb->cb_status); 779 + } 780 + /* 688 781 * RPC procedure tables 689 782 */ 690 783 #define PROC(proc, call, argtype, restype) \ ··· 800 703 PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout), 801 704 #endif 802 705 PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock), 706 + PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload), 803 707 }; 804 708 805 709 static unsigned int nfs4_cb_counts[ARRAY_SIZE(nfs4_cb_procedures)];
+1
fs/nfsd/state.h
··· 573 573 NFSPROC4_CLNT_CB_NULL = 0, 574 574 NFSPROC4_CLNT_CB_RECALL, 575 575 NFSPROC4_CLNT_CB_LAYOUT, 576 + NFSPROC4_CLNT_CB_OFFLOAD, 576 577 NFSPROC4_CLNT_CB_SEQUENCE, 577 578 NFSPROC4_CLNT_CB_NOTIFY_LOCK, 578 579 };
+6
fs/nfsd/xdr4.h
··· 511 511 u64 wr_bytes_written; 512 512 u32 wr_stable_how; 513 513 nfs4_verifier wr_verifier; 514 + stateid_t cb_stateid; 514 515 }; 515 516 516 517 struct nfsd4_copy { ··· 527 526 528 527 /* response */ 529 528 struct nfsd42_write_res cp_res; 529 + 530 + /* for cb_offload */ 531 + struct nfsd4_callback cp_cb; 532 + __be32 nfserr; 533 + struct knfsd_fh fh; 530 534 }; 531 535 532 536 struct nfsd4_seek {
+10
fs/nfsd/xdr4cb.h
··· 38 38 #define NFS4_dec_cb_notify_lock_sz (cb_compound_dec_hdr_sz + \ 39 39 cb_sequence_dec_sz + \ 40 40 op_dec_sz) 41 + #define enc_cb_offload_info_sz (1 + 1 + 2 + 1 + \ 42 + XDR_QUADLEN(NFS4_VERIFIER_SIZE)) 43 + #define NFS4_enc_cb_offload_sz (cb_compound_enc_hdr_sz + \ 44 + cb_sequence_enc_sz + \ 45 + enc_nfs4_fh_sz + \ 46 + enc_stateid_sz + \ 47 + enc_cb_offload_info_sz) 48 + #define NFS4_dec_cb_offload_sz (cb_compound_dec_hdr_sz + \ 49 + cb_sequence_dec_sz + \ 50 + op_dec_sz)