---
name: "sglist"
section: "9"
platform: "freebsd"
package: "base"
version: "16.0-CURRENT-20261027-61c70dc16a79"
release: "FreeBSD 16.0-CURRENT (2026-10-27)"
platforms: ["freebsd"]
url: "https://new.carta.tech/sglist"
---

# sglist(9)

manage a scatter/gather list of physical memory addresses

## NAME

**sglist**, **sglist\_alloc**, **sglist\_append**, **sglist\_append\_bio**, **sglist\_append\_mbuf**, **sglist\_append\_mbuf\_epg**, **sglist\_append\_phys**, **sglist\_append\_sglist**, **sglist\_append\_single\_mbuf**, **sglist\_append\_uio**, **sglist\_append\_user**, **sglist\_append\_vmpages**, **sglist\_build**, **sglist\_clone**, **sglist\_consume\_uio**, **sglist\_count**, **sglist\_count\_mbuf\_epg**, **sglist\_count\_vmpages**, **sglist\_free**, **sglist\_hold**, **sglist\_init**, **sglist\_join**, **sglist\_length**, **sglist\_reset**, **sglist\_slice**, **sglist\_split** – manage a scatter/gather list of physical memory addresses

## SYNOPSIS

**#include \<sys/types.h\>**

**#include \<sys/sglist.h\>**

*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\_epg**(*struct sglist \*sg*, *struct mbuf \*m*, *size\_t offset*, *size\_t len*);

*int*\

**sglist\_append\_mbuf**(*struct sglist \*sg*, *struct mbuf \*m*);

*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 len*);

*int*\

**sglist\_append\_single\_mbuf**(*struct sglist \*sg*, *struct mbuf \*m*);

*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*);

*int*\

**sglist\_append\_vmpages**(*struct sglist \*sg*, *vm\_page\_t \*m*, *size\_t pgoff*, *size\_t len*);

*struct* *sglist* *\**\

**sglist\_build**(*void \*buf*, *size\_t len*, *int mflags*);

*struct* *sglist* *\**\

**sglist\_clone**(*struct sglist \*sg*, *int mflags*);

*int*\

**sglist\_consume\_uio**(*struct sglist \*sg*, *struct uio \*uio*, *size\_t resid*);

*int*\

**sglist\_count**(*void \*buf*, *size\_t len*);

*int*\

**sglist\_count\_mbuf\_epg**(*struct mbuf \*m*, *size\_t offset*, *size\_t len*);

*int*\

**sglist\_count\_vmpages**(*vm\_page\_t \*m*, *size\_t pgoff*, *size\_t len*);

*void*\

**sglist\_free**(*struct sglist \*sg*);

*struct* *sglist* *\**\

**sglist\_hold**(*struct sglist \*sg*);

*void*\

**sglist\_init**(*struct sglist \*sg*, *int maxsegs*, *struct sglist\_seg \*segs*);

*int*\

**sglist\_join**(*struct sglist \*first*, *struct sglist \*second*);

*size\_t*\

**sglist\_length**(*struct sglist \*sg*);

*void*\

**sglist\_reset**(*struct sglist \*sg*);

*int*\

**sglist\_slice**(*struct sglist \*original*, *struct sglist \*\*slice*, *size\_t offset*, *size\_t length*, *int mflags*);

*int*\

**sglist\_split**(*struct sglist \*original*, *struct sglist \*\*head*, *size\_t length*, *int mflags*);

## DESCRIPTION

The **sglist** API manages physical address ranges. Each list contains one or more elements. Each element contains a starting physical address and a length. Scatter/gather lists are read-only while they are shared. If one wishes to alter an existing scatter/gather list and does not hold the sole reference to the list, then one should create a new list instead of modifying the existing list.

Each scatter/gather list object contains a reference count. New lists are created with a single reference. New references are obtained by calling **sglist\_hold** and are released by calling **sglist\_free**.

### Allocating and Initializing Lists

Each **sglist** object consists of a header structure and a variable-length array of scatter/gather list elements. The **sglist\_alloc** function allocates a new list that contains a header and *nsegs* scatter/gather list elements. The *mflags* argument can be set to either M\_NOWAIT or M\_WAITOK.

The **sglist\_count** function returns the number of scatter/gather list elements needed to describe the physical address ranges mapped by a single kernel virtual address range. The kernel virtual address range starts at *buf* and is *len* bytes long.

The **sglist\_count\_mbuf\_epg** function returns the number of scatter/gather list elements needed to describe the external multipage mbuf buffer *m*. The ranges start at an offset of *offset* relative to the start of the buffer and is *len* bytes long.

The **sglist\_count\_vmpages** function returns the number of scatter/gather list elements needed to describe the physical address ranges of a buffer backed by an array of virtual memory pages *m*. The buffer starts at an offset of *pgoff* bytes relative to the first page and is *len* bytes long.

The **sglist\_build** function allocates a new scatter/gather list object that describes the physical address ranges mapped by a single kernel virtual address range. The kernel virtual address range starts at *buf* and is *len* bytes long. The *mflags* argument can be set to either M\_NOWAIT or M\_WAITOK.

The **sglist\_clone** function returns a copy of an existing scatter/gather list object *sg*. The *mflags* argument can be set to either M\_NOWAIT or M\_WAITOK. This can be used to obtain a private copy of a scatter/gather list before modifying it.

The **sglist\_init** function initializes a scatter/gather list header. The header is pointed to by *sg* and is initialized to manage an array of *maxsegs* scatter/gather list elements pointed to by *segs*. This can be used to initialize a scatter/gather list header whose storage is not provided by **sglist\_alloc**. In that case, the caller should not call **sglist\_free** to release its own reference and is responsible for ensuring all other references to the list are dropped before it releases the storage for *sg* and *segs*.

### Constructing Scatter/Gather Lists

The **sglist** API provides several routines for building a scatter/gather list to describe one or more objects. Specifically, the **sglist\_append** family of routines can be used to append the physical address ranges described by an object to the end of a scatter/gather list. All of these routines return 0 on success or an error on failure. If a request to append an address range to a scatter/gather list fails, the scatter/gather list will remain unchanged.

The **sglist\_append** function appends the physical address ranges described by a single kernel virtual address range to the scatter/gather list *sg*. The kernel virtual address range starts at *buf* and is *len* bytes long.

The **sglist\_append\_bio** function appends the physical address ranges described by a single bio *bp* to the scatter/gather list *sg*.

The **sglist\_append\_mbuf\_epg** function appends the physical address ranges described by the external multipage [mbuf(9)](/mbuf/9.md) buffer *ext\_pgs* to the scatter/gather list *sg*. The physical address ranges start at offset *offset* within *ext\_pgs* and continue for *len* bytes. Note that unlike **sglist\_append\_mbuf**, **sglist\_append\_mbuf\_epg** only adds ranges for a single mbuf, not an entire mbuf chain.

The **sglist\_append\_mbuf** function appends the physical address ranges described by an entire mbuf chain *m* to the scatter/gather list *sg*.

The **sglist\_append\_single\_mbuf** function appends the physical address ranges described by a single mbuf *m* to the scatter/gather list *sg*.

The **sglist\_append\_phys** function appends a single physical address range to the scatter/gather list *sg*. The physical address range starts at *paddr* and is *len* bytes long.

The **sglist\_append\_sglist** function appends physical address ranges described by the scatter/gather list *source* to the scatter/gather list *sg*. The physical address ranges start at offset *offset* within *source* and continue for *len* bytes.

The **sglist\_append\_uio** function appends the physical address ranges described by a [uio(9)](/uio/9.md) object to the scatter/gather list *sg*. Note that it is the caller's responsibility to ensure that the pages backing the I/O request are wired for the lifetime of *sg*. Note also that this routine does not modify *uio*.

The **sglist\_append\_user** function appends the physical address ranges described by a single user virtual address range to the scatter/gather list *sg*. The user virtual address range is relative to the address space of the thread *td*. It starts at *buf* and is *len* bytes long. Note that it is the caller's responsibility to ensure that the pages backing the user buffer are wired for the lifetime of *sg*.

The **sglist\_append\_vmpages** function appends the physical address ranges of a buffer backed by an array of virtual memory pages *m*. The buffer starts at an offset of *pgoff* bytes relative to the first page and is *len* bytes long.

The **sglist\_consume\_uio** function is a variation of **sglist\_append\_uio**. As with **sglist\_append\_uio**, it appends the physical address ranges described by *uio* to the scatter/gather list *sg*. Unlike **sglist\_append\_uio**, however, **sglist\_consume\_uio** modifies the I/O request to indicate that the appended address ranges have been processed similar to calling [uiomove(9)](/uiomove/9.md). This routine will only append ranges that describe up to *resid* total bytes in length. If the available segments in the scatter/gather list are exhausted before *resid* bytes are processed, then the *uio* structure will be updated to reflect the actual number of bytes processed, and **sglist\_consume\_io** will return zero to indicate success. In effect, this function will perform partial reads or writes. The caller can compare the *uio\_resid* member of *uio* before and after calling **sglist\_consume\_uio** to determine the actual number of bytes processed.

### Manipulating Scatter/Gather Lists

The **sglist\_join** function appends physical address ranges from the scatter/gather list *second* onto *first* and then resets *second* to an empty list. It returns zero on success or an error on failure.

The **sglist\_split** function splits an existing scatter/gather list into two lists. The first *length* bytes described by the list *original* are moved to a new list *\*head*. If *original* describes a total address range that is smaller than *length* bytes, then all of the address ranges will be moved to the new list at *\*head* and *original* will be an empty list. The caller may supply an existing scatter/gather list in *\*head*. If so, the list must be empty. Otherwise, the caller may set *\*head* to NULL in which case a new scatter/gather list will be allocated. In that case, *mflags* may be set to either M\_NOWAIT or M\_WAITOK. Note that since the *original* list is modified by this call, it must be a private list with no other references. The **sglist\_split** function returns zero on success or an error on failure.

The **sglist\_slice** function generates a new scatter/gather list from a sub-range of an existing scatter/gather list *original*. The sub-range to extract is specified by the *offset* and *length* parameters. The new scatter/gather list is stored in *\*slice*. As with *head* for **sglist\_join**, the caller may either provide an empty scatter/gather list, or it may set *\*slice* to NULL in which case **sglist\_slice** will allocate a new list subject to *mflags*. Unlike **sglist\_split**, **sglist\_slice** does not modify *original* and does not require it to be a private list. The **sglist\_split** function returns zero on success or an error on failure.

### Miscellaneous Routines

The **sglist\_reset** function clears the scatter/gather list *sg* so that it no longer maps any address ranges. This can allow reuse of a single scatter/gather list object for multiple requests.

The **sglist\_length** function returns the total length of the physical address ranges described by the scatter/gather list *sg*.

## RETURN VALUES

The **sglist\_alloc**, **sglist\_build**, and **sglist\_clone** functions return a new scatter/gather list on success or NULL on failure.

The **sglist\_append** family of functions and the **sglist\_consume\_uio**, **sglist\_join**, **sglist\_slice**, and **sglist\_split** functions return zero on success or an error on failure.

The **sglist\_count** family of functions return a count of scatter/gather list elements.

The **sglist\_length** function returns a count of address space described by a scatter/gather list in bytes.

## ERRORS

The **sglist\_append** functions return the following errors on failure:

- \[EINVAL\]

  The scatter/gather list has zero segments.

- \[EFBIG\]

  There are not enough available segments in the scatter/gather list to append the specified physical address ranges.

The **sglist\_consume\_uio** function returns the following error on failure:

- \[EINVAL\]

  The scatter/gather list has zero segments.

The **sglist\_join** function returns the following error on failure:

- \[EFBIG\]

  There are not enough available segments in the scatter/gather list *first* to append the physical address ranges from *second*.

The **sglist\_slice** function returns the following errors on failure:

- \[EINVAL\]

  The *original* scatter/gather list does not describe enough address space to cover the requested sub-range.

- \[EINVAL\]

  The caller-supplied scatter/gather list in *\*slice* is not empty.

- \[ENOMEM\]

  An attempt to allocate a new scatter/gather list with M\_NOWAIT set in *mflags* failed.

- \[EFBIG\]

  There are not enough available segments in the caller-supplied scatter/gather list in *\*slice* to describe the requested physical address ranges.

The **sglist\_split** function returns the following errors on failure:

- \[EDOOFUS\]

  The *original* scatter/gather list has more than one reference.

- \[EINVAL\]

  The caller-supplied scatter/gather list in *\*head* is not empty.

- \[ENOMEM\]

  An attempt to allocate a new scatter/gather list with M\_NOWAIT set in *mflags* failed.

- \[EFBIG\]

  There are not enough available segments in the caller-supplied scatter/gather list in *\*head* to describe the requested physical address ranges.

## SEE ALSO

[g\_bio(9)](/g_bio/9.md), [malloc(9)](/malloc/9.md), [mbuf(9)](/mbuf/9.md), [uio(9)](/uio/9.md)

## HISTORY

This API was first introduced in FreeBSD 8.0.
