buf(9S)
NAME
buf − block I/O data transfer structure
SYNOPSIS
#include <sys/buf.h>
INTERFACE LEVEL
Architecture independent level 1 (DDI/DKI).
DESCRIPTION
The buf structure is the basic data structure for block I/O transfers. Each block I/O transfer has an associated buffer header. The header contains all the buffer control and status information. For drivers, the buffer header pointer is the sole argument to a block driver strategy(9E) routine. Do not depend on the size of the buf structure when writing a driver.
It is important to note that a buffer header may be linked in multiple lists simultaneously. Because of this, most of the members in the buffer header cannot be changed by the driver, even when the buffer header is in one of the drivers’ work lists.
Buffer headers are also used by the system for unbuffered or physical I/O for block drivers. In this case, the buffer describes a portion of user data space that is locked into memory.
Block drivers often chain block requests so that overall throughput for the device is maximized. The av_forw and the av_back members of the buf structure can serve as link pointers for chaining block requests.
The following figure illustrates two linked lists of buffers. The top illustration is the bfreelist, the list of available buffers. The bottom illustration is a queue of allocated buffers. The lined areas indicate other buffer members.
scale=100
define m0 |
[ box invis ht 88 wid 80 with .sw at 0,0
"b_back" at 42,15
line from 0,30 to 80,30
line from 50,58 to 22,88
line from 14,58 to 0,74
line from 58,58 to 28,88
box ht 88 wid 80 with .nw at 0,88
"b_forw" at 40,43
line from 80,58 to 50,88
line from 6,58 to 0,66
line from 0,58 to 80,58
line from 36,58 to 6,88
line from 80,74 to 64,88
line from 72,58 to 42,88
line from 42,58 to 14,88
line from 22,58 to 0,80
line from 64,58 to 36,88
line from 28,58 to 0,88
line from 80,80 to 72,88
line from 80,66 to 58,88
] |
define m1 |
[ box invis ht 86 wid 80 with .sw at 0,0
line from 44,28 to 16,0
line from 16,28 to 0,14
line from 36,28 to 8,0
line from 8,28 to 0,22
line from 0,28 to 80,28
line from 52,28 to 22,0
line from 58,28 to 30,0
line from 22,28 to 0,6
line from 74,28 to 44,0
line from 80,28 to 52,0
line from 80,14 to 66,0
box ht 86 wid 80 with .nw at 0,86
line from 80,6 to 74,0
line from 66,28 to 36,0
line from 80,22 to 58,0
line from 30,28 to 0,0
"av_forw" at 40,73
"av_back" at 40,41
line from 0,58 to 80,58
] |
box invis ht 296 wid 352 with .sw at 0,0
"buf structures" at 240,289
"bfreelist" at 32,283
line -> from 80,254 to 132,254
line -> from 212,254 to 262,254
m1 with .nw at 262,268
m1 with .nw at 132,268
m1 with .nw at 0,268
line <- from 84,250 to 132,224
"Available Buffers" at 240,157
line from 342,174 to 350,182
line from 132,174 to 124,182
line from 132,174 to 342,174
line <- from 214,250 to 262,224
"Allocated Buffers" at 240,-7
". . ." at 372,68
line from 342,12 to 350,18
line from 132,12 to 342,12
line from 132,12 to 124,18
line -> from 260,32 to 216,90
line -> from 132,34 to 88,90
line -> from 212,62 to 258,90
line -> from 84,62 to 128,90
m0 with .nw at 4,106
m0 with .nw at 260,106
m0 with .nw at 132,106
". . ." at 372,226
STRUCTURE MEMBERS
| int | b_flags; | /∗ Buffer status ∗/ |
| struct buf | ∗b_forw; | /∗ headed by d_tab of conf.c ∗/ |
| struct buf | ∗b_back; | /∗ headed by d_tab of conf.c ∗/ |
| struct buf | ∗av_forw; | /∗ Driver work list link ∗/ |
| struct buf | ∗av_back; | /∗ Driver work lists link ∗/ |
| o_dev_t | b_dev; | /∗ Major/minor device numbers ∗/ |
| unsigned | b_bcount; | /∗ # of bytes to transfer ∗/ |
| caddr_t | b_addr; | /∗ Buffer’s virtual address ∗/ |
| daddr_t | b_blkno; | /∗ Block number on device ∗/ |
| char | b_oerror; | /∗ Old post-I/O error number ∗/ |
| unsigned int | b_resid; | /∗ # of bytes not transferred ∗/ |
| clock_t | b_start; | /∗ request start time ∗/ |
| struct proc | ∗b_proc; | /∗ Process table entry address ∗/ |
| struct page | ∗b_pages; | /∗ page list for PAGEIO ∗/ |
| clock_t | b_realtime; | /∗ previous release time ∗/ |
| long | b_bufsize; | /∗ size of allocated buffer ∗/ |
| int | (∗b_iodone)(); | /∗ function called by biodone ∗/ |
| struct vnode | ∗b_vp; | /∗ vnode associated with block ∗/ |
| int | b_error; | /∗ expanded error field ∗/ |
| dev_t | b_edev; | /∗ expanded dev field ∗/ |
The paddr macro (defined in buf.h) provides access to the b_un.b_addr member of the buf structure. ( b_un is a union that contains b_addr.)
The members of the buffer header available to test or set by a driver are as follows:
b_flags stores the buffer status and tells the driver whether to read or write to the device. The driver must never clear the b_flags member. If this is done, unpredictable results can occur including loss of disk sanity and the possible failure of other kernel processes.
Valid flags are as follows:
B_BUSY indicates the buffer is in use.
B_DONE indicates the data transfer has completed.
B_ERROR indicates an I/O transfer error.
B_KERNBUF indicates the buffer is allocated by the kernel and not by a driver.
B_PAGEIO indicates the buffer is being used in a paged I/O request. If B_PAGEIO is set, the b_pages field of the buffer header will point to a sorted list of page structures. Also, the b_addr field of the buffer header will be offset into the first page of the page list. If B_PAGEIO is not set, the b_addr field of the buffer header will contain the kernel virtual address of the I/O request. The b_pages field of the buffer header is not used.
B_PHYS indicates the buffer header is being used for physical (direct) I/O to a user data area. The b_un member contains the starting address of the user data area.
B_READ indicates data is to be read from the peripheral device into main memory.
B_WANTED indicates the buffer is sought for allocation.
B_WRITE indicates the data is to be transferred from main memory to the peripheral device. B_WRITE is a pseudo flag that occupies the same bit location as B_READ. B_WRITE cannot be directly tested; it is only detected as the NOT form of B_READ.
av_forw and av_back can be used by the driver to link the buffer into driver work lists.
b_dev contains the external major and minor device numbers of the device accessed. For Release 4.0, this field is replaced by the expanded device number field b_edev. b_dev is maintained for compatibility.
b_bcount specifies the number of bytes to be transferred in both a paged and a non-paged I/O request.
b_addr is either the virtual address of the I/O request, or an offset into the first page of a page list depending on whether B_PAGEIO is set. If it is set, the b_pages field of the buffer header will point to a sorted list of page structures and b_addr will be the offset into the first page. If B_PAGEIO is not set, b_addr is the virtual address from which data is read or to which data is written.
b_blkno identifies which logical block on the device (the device is defined by the device number) is to be accessed. The driver may have to convert this logical block number to a physical location such as a cylinder, track, and sector of a disk.
The b_oerror with a char data type and the expanded b_error with an int data type both may hold an error code that should be passed as a return code from your driver routine. b_error and b_oerror is set in conjunction with the B_ERROR flag (set by the operating system in the b_flags member).
b_resid indicates the number of bytes not transferred because of an error.
b_start holds the time the I/O request was started.
b_proc contains the process table entry address for the process requesting an unbuffered (direct) data transfer to a user data area (this member is set to 0 when the transfer is buffered). The process table entry is used to perform proper virtual to physical address translation of the b_un member.
b_pages contains a pointer to the page structure list used in a paged I/O operation.
b_bufsize contains the size of the allocated buffer.
(∗b_iodone)() identifies a specific biodone routine to be called by the driver when the I/O is complete.
b_vp identifies the vnode associated with the block.
SEE ALSO
strategy(9E), brelse(9F), clrbuf(9F), iovec(9S), physio(9F), uio(9S)
WARNINGS
Buffers are a shared resource within the kernel. Drivers should read or write only the members listed in this section. Drivers that attempt to use undocumented members of the buf structure risk corrupting data in the kernel or on the device.
SunOS 5.2 — Last change: 11 Apr 1991