Add sglist_append_bio(9) to append a struct bio's data to a sglist
Reviewed by: jhb, kib (long ago)
This commit is contained in:
parent
eff1b62808
commit
c35dbac21a
@ -1185,6 +1185,7 @@ MLINKS+=sf_buf.9 sf_buf_alloc.9 \
|
||||
sf_buf.9 sf_buf_page.9
|
||||
MLINKS+=sglist.9 sglist_alloc.9 \
|
||||
sglist.9 sglist_append.9 \
|
||||
sglist.9 sglist_append_bio.9 \
|
||||
sglist.9 sglist_append_mbuf.9 \
|
||||
sglist.9 sglist_append_phys.9 \
|
||||
sglist.9 sglist_append_uio.9 \
|
||||
|
@ -26,13 +26,14 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 15, 2009
|
||||
.Dd January 12, 2014
|
||||
.Dt SGLIST 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sglist ,
|
||||
.Nm sglist_alloc ,
|
||||
.Nm sglist_append ,
|
||||
.Nm sglist_append_bio ,
|
||||
.Nm sglist_append_mbuf ,
|
||||
.Nm sglist_append_phys ,
|
||||
.Nm sglist_append_uio ,
|
||||
@ -58,6 +59,8 @@
|
||||
.Ft int
|
||||
.Fn sglist_append "struct sglist *sg" "void *buf" "size_t len"
|
||||
.Ft int
|
||||
.Fn sglist_append_bio "struct sglist *sg" "struct bio *bp"
|
||||
.Ft int
|
||||
.Fn sglist_append_mbuf "struct sglist *sg" "struct mbuf *m"
|
||||
.Ft int
|
||||
.Fn sglist_append_phys "struct sglist *sg" "vm_paddr_t paddr" "size_t len"
|
||||
@ -206,6 +209,13 @@ and is
|
||||
bytes long.
|
||||
.Pp
|
||||
The
|
||||
.Nm sglist_append_bio
|
||||
function appends the physical address ranges described by a single bio
|
||||
.Fa bp
|
||||
to the scatter/gather list
|
||||
.Fa sg .
|
||||
.Pp
|
||||
The
|
||||
.Nm sglist_append_mbuf
|
||||
function appends the physical address ranges described by an entire mbuf
|
||||
chain
|
||||
@ -499,6 +509,7 @@ list in
|
||||
to describe the requested physical address ranges.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr g_bio 9 ,
|
||||
.Xr malloc 9 ,
|
||||
.Xr mbuf 9 ,
|
||||
.Xr uio 9
|
||||
|
@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/proc.h>
|
||||
@ -40,6 +41,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_map.h>
|
||||
|
||||
@ -238,6 +240,44 @@ sglist_append(struct sglist *sg, void *buf, size_t len)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append the segments to describe a bio's data to a scatter/gather list.
|
||||
* If there are insufficient segments, then this fails with EFBIG.
|
||||
*
|
||||
* NOTE: This function expects bio_bcount to be initialized.
|
||||
*/
|
||||
int
|
||||
sglist_append_bio(struct sglist *sg, struct bio *bp)
|
||||
{
|
||||
struct sgsave save;
|
||||
vm_paddr_t paddr;
|
||||
size_t len, tlen;
|
||||
int error, i, ma_offs;
|
||||
|
||||
if ((bp->bio_flags & BIO_UNMAPPED) == 0) {
|
||||
error = sglist_append(sg, bp->bio_data, bp->bio_bcount);
|
||||
return (error);
|
||||
}
|
||||
|
||||
if (sg->sg_maxseg == 0)
|
||||
return (EINVAL);
|
||||
|
||||
SGLIST_SAVE(sg, save);
|
||||
tlen = bp->bio_bcount;
|
||||
ma_offs = bp->bio_ma_offset;
|
||||
for (i = 0; tlen > 0; i++, tlen -= len) {
|
||||
len = min(PAGE_SIZE - ma_offs, tlen);
|
||||
paddr = VM_PAGE_TO_PHYS(bp->bio_ma[i]) + ma_offs;
|
||||
error = sglist_append_phys(sg, paddr, len);
|
||||
if (error) {
|
||||
SGLIST_RESTORE(sg, save);
|
||||
return (error);
|
||||
}
|
||||
ma_offs = 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a single physical address range to a scatter/gather list.
|
||||
* If there are insufficient segments, then this fails with EFBIG.
|
||||
|
@ -53,6 +53,7 @@ struct sglist {
|
||||
u_short sg_maxseg;
|
||||
};
|
||||
|
||||
struct bio;
|
||||
struct mbuf;
|
||||
struct uio;
|
||||
|
||||
@ -83,6 +84,7 @@ sglist_hold(struct sglist *sg)
|
||||
|
||||
struct sglist *sglist_alloc(int nsegs, int mflags);
|
||||
int sglist_append(struct sglist *sg, void *buf, size_t len);
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user