Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Mar 2019 22:48:51 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r345039 - in stable/11: share/man/man9 sys/kern sys/sys
Message-ID:  <201903112248.x2BMmptp076749@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Mon Mar 11 22:48:51 2019
New Revision: 345039
URL: https://svnweb.freebsd.org/changeset/base/345039

Log:
  MFC 318388: Add sglist_append_sglist().
  
  This function permits a range of one scatter/gather list to be appended to
  another sglist.  This can be used to construct a scatter/gather list that
  reorders or duplicates ranges from one or more existing scatter/gather
  lists.
  
  Sponsored by:	Chelsio Communications

Modified:
  stable/11/share/man/man9/Makefile
  stable/11/share/man/man9/sglist.9
  stable/11/sys/kern/subr_sglist.c
  stable/11/sys/sys/sglist.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/share/man/man9/Makefile
==============================================================================
--- stable/11/share/man/man9/Makefile	Mon Mar 11 22:43:24 2019	(r345038)
+++ stable/11/share/man/man9/Makefile	Mon Mar 11 22:48:51 2019	(r345039)
@@ -1593,6 +1593,7 @@ MLINKS+=sglist.9 sglist_alloc.9 \
 	sglist.9 sglist_append_bio.9 \
 	sglist.9 sglist_append_mbuf.9 \
 	sglist.9 sglist_append_phys.9 \
+	sglist.9 sglist_append_sglist.9 \
 	sglist.9 sglist_append_uio.9 \
 	sglist.9 sglist_append_user.9 \
 	sglist.9 sglist_append_vmpages.9 \

Modified: stable/11/share/man/man9/sglist.9
==============================================================================
--- stable/11/share/man/man9/sglist.9	Mon Mar 11 22:43:24 2019	(r345038)
+++ stable/11/share/man/man9/sglist.9	Mon Mar 11 22:48:51 2019	(r345039)
@@ -26,7 +26,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 12, 2014
+.Dd May 16, 2017
 .Dt SGLIST 9
 .Os
 .Sh NAME
@@ -36,6 +36,7 @@
 .Nm sglist_append_bio ,
 .Nm sglist_append_mbuf ,
 .Nm sglist_append_phys ,
+.Nm sglist_append_sglist ,
 .Nm sglist_append_uio ,
 .Nm sglist_append_user ,
 .Nm sglist_append_vmpages ,
@@ -67,6 +68,8 @@
 .Ft int
 .Fn sglist_append_phys "struct sglist *sg" "vm_paddr_t paddr" "size_t len"
 .Ft int
+.Fn sglist_append_sglist "struct sglist *sg" "struct sglist *source" "size_t offset" "size_t len"
+.Ft int
 .Fn sglist_append_uio "struct sglist *sg" "struct uio *uio"
 .Ft int
 .Fn sglist_append_user "struct sglist *sg" "void *buf" "size_t len" "struct thread *td"
@@ -250,6 +253,20 @@ The physical address range starts at
 and is
 .Fa len
 bytes long.
+.Pp
+The
+.Nm sglist_append_sglist
+function appends physical address ranges described by the scatter/gather list
+.Fa source
+to the scatter/gather list
+.Fa sg .
+The physical address ranges start at offset
+.Fa offset
+within
+.Fa source
+and continue for
+.Fa len
+bytes.
 .Pp
 The
 .Nm sglist_append_uio

Modified: stable/11/sys/kern/subr_sglist.c
==============================================================================
--- stable/11/sys/kern/subr_sglist.c	Mon Mar 11 22:43:24 2019	(r345038)
+++ stable/11/sys/kern/subr_sglist.c	Mon Mar 11 22:48:51 2019	(r345039)
@@ -413,6 +413,49 @@ sglist_append_user(struct sglist *sg, void *buf, size_
 }
 
 /*
+ * Append a subset of an existing scatter/gather list 'source' to a
+ * the scatter/gather list 'sg'.  If there are insufficient segments,
+ * then this fails with EFBIG.
+ */
+int
+sglist_append_sglist(struct sglist *sg, struct sglist *source, size_t offset,
+    size_t length)
+{
+	struct sgsave save;
+	struct sglist_seg *ss;
+	size_t seglen;
+	int error, i;
+
+	if (sg->sg_maxseg == 0 || length == 0)
+		return (EINVAL);
+	SGLIST_SAVE(sg, save);
+	error = EINVAL;
+	ss = &sg->sg_segs[sg->sg_nseg - 1];
+	for (i = 0; i < source->sg_nseg; i++) {
+		if (offset >= source->sg_segs[i].ss_len) {
+			offset -= source->sg_segs[i].ss_len;
+			continue;
+		}
+		seglen = source->sg_segs[i].ss_len - offset;
+		if (seglen > length)
+			seglen = length;
+		error = _sglist_append_range(sg, &ss,
+		    source->sg_segs[i].ss_paddr + offset, seglen);
+		if (error)
+			break;
+		offset = 0;
+		length -= seglen;
+		if (length == 0)
+			break;
+	}
+	if (length != 0)
+		error = EINVAL;
+	if (error)
+		SGLIST_RESTORE(sg, save);
+	return (error);
+}
+
+/*
  * Append the segments that describe a single uio to a scatter/gather
  * list.  If there are insufficient segments, then this fails with
  * EFBIG.

Modified: stable/11/sys/sys/sglist.h
==============================================================================
--- stable/11/sys/sys/sglist.h	Mon Mar 11 22:43:24 2019	(r345038)
+++ stable/11/sys/sys/sglist.h	Mon Mar 11 22:48:51 2019	(r345039)
@@ -88,6 +88,8 @@ int	sglist_append_bio(struct sglist *sg, struct bio *b
 int	sglist_append_mbuf(struct sglist *sg, struct mbuf *m0);
 int	sglist_append_phys(struct sglist *sg, vm_paddr_t paddr,
 	    size_t len);
+int	sglist_append_sglist(struct sglist *sg, struct sglist *source,
+	    size_t offset, size_t length);
 int	sglist_append_uio(struct sglist *sg, struct uio *uio);
 int	sglist_append_user(struct sglist *sg, void *buf, size_t len,
 	    struct thread *td);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201903112248.x2BMmptp076749>