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>