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
This commit is contained in:
parent
720e7bb69c
commit
00f6cd3f56
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=318388
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -412,6 +412,49 @@ sglist_append_user(struct sglist *sg, void *buf, size_t len, struct thread *td)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -88,6 +88,8 @@ int sglist_append_bio(struct sglist *sg, struct bio *bp);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user