Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 May 2017 23:31:52 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r318388 - in head: share/man/man9 sys/kern sys/sys
Message-ID:  <201705162331.v4GNVqRj090497@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Tue May 16 23:31:52 2017
New Revision: 318388
URL: https://svnweb.freebsd.org/changeset/base/318388

Log:
  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:
  head/share/man/man9/Makefile
  head/share/man/man9/sglist.9
  head/sys/kern/subr_sglist.c
  head/sys/sys/sglist.h

Modified: head/share/man/man9/Makefile
==============================================================================
--- head/share/man/man9/Makefile	Tue May 16 23:18:50 2017	(r318387)
+++ head/share/man/man9/Makefile	Tue May 16 23:31:52 2017	(r318388)
@@ -1572,6 +1572,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: head/share/man/man9/sglist.9
==============================================================================
--- head/share/man/man9/sglist.9	Tue May 16 23:18:50 2017	(r318387)
+++ head/share/man/man9/sglist.9	Tue May 16 23:31:52 2017	(r318388)
@@ -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"
@@ -252,6 +255,20 @@ and is
 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
 function appends the physical address ranges described by a
 .Xr uio 9

Modified: head/sys/kern/subr_sglist.c
==============================================================================
--- head/sys/kern/subr_sglist.c	Tue May 16 23:18:50 2017	(r318387)
+++ head/sys/kern/subr_sglist.c	Tue May 16 23:31:52 2017	(r318388)
@@ -413,6 +413,49 @@ sglist_append_user(struct sglist *sg, vo
 }
 
 /*
+ * 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: head/sys/sys/sglist.h
==============================================================================
--- head/sys/sys/sglist.h	Tue May 16 23:18:50 2017	(r318387)
+++ head/sys/sys/sglist.h	Tue May 16 23:31:52 2017	(r318388)
@@ -88,6 +88,8 @@ int	sglist_append_bio(struct sglist *sg,
 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?201705162331.v4GNVqRj090497>