// SPDX-License-Identifier: GPL-2.0-only /* * linux/net/sunrpc/socklib.c * * Common socket helper routines for RPC client and server * * Copyright (C) 1995, 1996 Olaf Kirch <[email protected]> */ #include <linux/compiler.h> #include <linux/netdevice.h> #include <linux/gfp.h> #include <linux/skbuff.h> #include <linux/types.h> #include <linux/pagemap.h> #include <linux/udp.h> #include <linux/sunrpc/msg_prot.h> #include <linux/sunrpc/sched.h> #include <linux/sunrpc/xdr.h> #include <linux/export.h> #include "socklib.h" /* * Helper structure for copying from an sk_buff. */ struct xdr_skb_reader { … }; xdr_skb_read_actor; /** * xdr_skb_read_bits - copy some data bits from skb to internal buffer * @desc: sk_buff copy helper * @to: copy destination * @len: number of bytes to copy * * Possibly called several times to iterate over an sk_buff and copy * data out of it. */ static size_t xdr_skb_read_bits(struct xdr_skb_reader *desc, void *to, size_t len) { … } /** * xdr_skb_read_and_csum_bits - copy and checksum from skb to buffer * @desc: sk_buff copy helper * @to: copy destination * @len: number of bytes to copy * * Same as skb_read_bits, but calculate a checksum at the same time. */ static size_t xdr_skb_read_and_csum_bits(struct xdr_skb_reader *desc, void *to, size_t len) { … } /** * xdr_partial_copy_from_skb - copy data out of an skb * @xdr: target XDR buffer * @base: starting offset * @desc: sk_buff copy helper * @copy_actor: virtual method for copying data * */ static ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, struct xdr_skb_reader *desc, xdr_skb_read_actor copy_actor) { … } /** * csum_partial_copy_to_xdr - checksum and copy data * @xdr: target XDR buffer * @skb: source skb * * We have set things up such that we perform the checksum of the UDP * packet in parallel with the copies into the RPC client iovec. -DaveM */ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb) { … } EXPORT_SYMBOL_GPL(…); static inline int xprt_sendmsg(struct socket *sock, struct msghdr *msg, size_t seek) { … } static int xprt_send_kvec(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t seek) { … } static int xprt_send_pagedata(struct socket *sock, struct msghdr *msg, struct xdr_buf *xdr, size_t base) { … } /* Common case: * - stream transport * - sending from byte 0 of the message * - the message is wholly contained in @xdr's head iovec */ static int xprt_send_rm_and_kvec(struct socket *sock, struct msghdr *msg, rpc_fraghdr marker, struct kvec *vec, size_t base) { … } /** * xprt_sock_sendmsg - write an xdr_buf directly to a socket * @sock: open socket to send on * @msg: socket message metadata * @xdr: xdr_buf containing this request * @base: starting position in the buffer * @marker: stream record marker field * @sent_p: return the total number of bytes successfully queued for sending * * Return values: * On success, returns zero and fills in @sent_p. * %-ENOTSOCK if @sock is not a struct socket. */ int xprt_sock_sendmsg(struct socket *sock, struct msghdr *msg, struct xdr_buf *xdr, unsigned int base, rpc_fraghdr marker, unsigned int *sent_p) { … }