2022-05-11 09:10:08

by Joe Damato

[permalink] [raw]
Subject: [RFC,net-next 4/6] net: Add a struct for managing copy functions

Add struct skb_copier which encapsulates two functions for copying data,
and provide a default copier, skb_copier.

Separate skb_copy_datagram_from_iter into a a helper function,
do_skb_copy_datagram, which takes a struct skb_copier.

Signed-off-by: Joe Damato <[email protected]>
---
net/core/datagram.c | 49 ++++++++++++++++++++++++++++++++-----------------
1 file changed, 32 insertions(+), 17 deletions(-)

diff --git a/net/core/datagram.c b/net/core/datagram.c
index 50f4fae..a87c41b 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -532,18 +532,19 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset,
}
EXPORT_SYMBOL(skb_copy_datagram_iter);

-/**
- * skb_copy_datagram_from_iter - Copy a datagram from an iov_iter.
- * @skb: buffer to copy
- * @offset: offset in the buffer to start copying to
- * @from: the copy source
- * @len: amount of data to copy to buffer from iovec
- *
- * Returns 0 or -EFAULT.
- */
-int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,
- struct iov_iter *from,
- int len)
+struct skb_copier {
+ size_t (*copy_from_iter)(void *addr, size_t bytes, struct iov_iter *i);
+ size_t (*copy_page_from_iter)(struct page *page, size_t offset, size_t bytes,
+ struct iov_iter *i);
+};
+
+struct skb_copier skb_copier = {
+ .copy_from_iter = copy_from_iter,
+ .copy_page_from_iter = copy_page_from_iter
+};
+
+static int do_skb_copy_datagram(struct sk_buff *skb, int offset,
+ struct iov_iter *from, int len, struct skb_copier copier)
{
int start = skb_headlen(skb);
int i, copy = start - offset;
@@ -553,7 +554,7 @@ int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,
if (copy > 0) {
if (copy > len)
copy = len;
- if (copy_from_iter(skb->data + offset, copy, from) != copy)
+ if (copier.copy_from_iter(skb->data + offset, copy, from) != copy)
goto fault;
if ((len -= copy) == 0)
return 0;
@@ -573,7 +574,7 @@ int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,

if (copy > len)
copy = len;
- copied = copy_page_from_iter(skb_frag_page(frag),
+ copied = copier.copy_page_from_iter(skb_frag_page(frag),
skb_frag_off(frag) + offset - start,
copy, from);
if (copied != copy)
@@ -595,9 +596,7 @@ int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,
if ((copy = end - offset) > 0) {
if (copy > len)
copy = len;
- if (skb_copy_datagram_from_iter(frag_iter,
- offset - start,
- from, copy))
+ if (do_skb_copy_datagram(frag_iter, offset - start, from, copy, copier))
goto fault;
if ((len -= copy) == 0)
return 0;
@@ -611,6 +610,22 @@ int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,
fault:
return -EFAULT;
}
+
+/**
+ * skb_copy_datagram_from_iter - Copy a datagram from an iov_iter.
+ * @skb: buffer to copy
+ * @offset: offset in the buffer to start copying to
+ * @from: the copy source
+ * @len: amount of data to copy to buffer from iovec
+ *
+ * Returns 0 or -EFAULT.
+ */
+int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,
+ struct iov_iter *from,
+ int len)
+{
+ return do_skb_copy_datagram(skb, offset, from, len, skb_copier);
+}
EXPORT_SYMBOL(skb_copy_datagram_from_iter);

int __zerocopy_sg_from_iter(struct sock *sk, struct sk_buff *skb,
--
2.7.4