'\"!  pic | tbl | mmdoc
'\"macro stdmacro
.if n .pH ddi_dki.buf @(#)buf	40.7 of 10/10/89
.\" Copyright 1989 AT&T
.de IX
.ie '\\n(.z'' .tm .Index: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9	\\n%
.el \\!.IX \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
..
.nr X
.if \nX=0 .ds x} buf D4DK "" "DDI/DKI" "\&"
.if \nX=1 .ds x} buf D4DK "" "DDI/DKI"
.if \nX=2 .ds x} buf D4DK "" "\&"
.if \nX=3 .ds x} buf "" "" "\&"
.TH \*(x}
.IX "\f4buf\fP(D4DK)"
.SH NAME
\f4buf\f1 \- block I/O data transfer structure
.SH SYNOPSIS
\f4#include <sys/buf.h>\f1
.SH DESCRIPTION
.IX "\f4strategy\fP(D2DK)"
.IX "buffer header, \f4buf\fP(D4DK)
.IX "block I/O, \f4buf\fP(D4DK)"
The \f4buf\f1 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 \f4strategy\f1(D2DK) routine.  
Do not depend on the size of the \f4buf\f1 structure
when writing a driver.
.P
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.
.P
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 (see \f4physiock\f1(D3D)).
.P
Block drivers often chain block requests so that overall throughput for the
device is maximized.  The \f4av_forw\f1 and the \f4av_back\f1 members of the
\f4buf\f1 structure can serve as link pointers for chaining block
requests.
.P
The following figure illustrates two linked lists of buffers.
The top illustration is the \f4bfreelist\f1, the list of available buffers.  
The bottom illustration is a queue of allocated buffers.
The lined areas indicate other buffer members.
.nf
.PS 2.5
scale=100
define m0 |
[ box invis ht 88 wid 80 with .sw at 0,0
"\fR\s8\&\f4b_back\fP\f1\s0" 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 
"\fR\s8\&\f4b_forw\fP\f1\s0" 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 
"\fR\s8\&\f4av_forw\fP\f1\s0" at 40,73
"\fR\s8\&\f4av_back\fP\f1\s0" at 40,41
line  from 0,58 to 80,58 
] |

box invis ht 296 wid 352 with .sw at 0,0
"\fH\s8\&\f4buf\f1 structures\s0" at 240,289
"\fR\s8\&\f4bfreelist\f1\s0" 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 
"\fH\s8\&Available Buffers\f1\s0" 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 
"\fH\s8\&Allocated Buffers\f1\s0" at 240,-7
"\fB\s12\&. . .\f1\s0" 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
"\fB\s12\&. . .\f1\s0" at 372,226
.PE
.fi
.SH STRUCTURE MEMBERS
.TS
lf4p8 2 lf4p8 2 lf4p8.
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 */
unsigned long	b_reltime;	/* 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 */
.TE
.P
\f3CAUTION:\fP 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
\f4buf\fP structure risk corrupting data in the kernel or on the
device.
.P
The \f4paddr\f1 macro (defined in \f4buf.h\f1) provides access
to the \f4b_un.b_addr\f1 member of the \f4buf\f1 structure.
(\f4b_un\f1 is a union that contains \f4b_addr\f1.)
.P
The members of the buffer header available to test or set by a driver 
are as follows:
.P
\f4b_flags\f1
stores the buffer status and tells the driver whether to read or
write to the device.  The driver must never clear the \f4b_flags\fP
member.  If this is done, unpredictable results can occur including
loss of disk sanity and the possible failure of other kernel
processes.
.P
Valid flags are as follows:
.RS
.IP \f4B_BUSY\f1 14n
indicates the buffer is in use.
.IP \f4B_DONE\f1
indicates the data transfer has completed.
.IP \f4B_ERROR\f1
indicates an I/O transfer error.
.IP \f4B_KERNBUF\f1
indicates the buffer is allocated by the kernel and not by a driver.
.IP \f4B_PAGEIO\f1
indicates the buffer is being used in a paged I/O request.  If \f4B_PAGEIO\f1
is set, the \f4b_pages\f1 field of the buffer header will point to a
sorted list of page structures.  Also, the \f4b_addr\f1 field of the
buffer header will be offset into the first page of the page list.  If
\f4B_PAGEIO\f1 is not set, the \f4b_addr\f1 field of the buffer header will
contain the kernel virtual address of the I/O request.  The
\f4b_pages\f1 field of the buffer header is not used.
.IP \f4B_PHYS\f1
indicates the buffer header is being used for physical (direct) I/O to a user
data area.  The \f4b_un\f1 member contains the starting address of the user
data area.
.IP \f4B_READ\f1
indicates data is to be read from the peripheral device into main memory.
.IP \f4B_WANTED\f1
indicates the buffer is sought for allocation.
.IP \f4B_WRITE\f1
indicates the data is to be
transferred from main memory to the peripheral device.
\f4B_WRITE\f1 is a pseudo flag that occupies the same bit location as \f4B_READ\f1.
\f4B_WRITE\f1 cannot be directly tested; it is only detected as the NOT
form of \f4B_READ\f1.
.RE
.P
\f4av_forw\f1 and \f4av_back\f1 can be used by the driver to link
the buffer into driver work lists.
.P 
\f4b_dev\f1 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 \f4b_edev\f1.  \f4b_dev\f1 is maintained for
compatibility.
.P
\f4b_bcount\f1 specifies the number of bytes to be transferred in both
a paged and a non-paged I/O request.
.P
\f4b_addr\f1 is either the virtual address of the I/O request, or an
offset into the first page of a page list depending on whether \f4B_PAGEIO\f1
is set.  If it is set, the \f4b_pages\f1 field of the buffer header
will point to a sorted list of page structures and \f4b_addr\f1 will
be the offset into the first page.  If \f4B_PAGEIO\f1 is not set,
\f4b_addr\f1 is the virtual address from which data is read or to
which data is written.
.P
\f4b_blkno\f1 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.
.P
The \f4b_oerror\f1 with a \f4char\f1 data type and the expanded
\f4b_error\f1 with an \f4int\f1 data type both may hold an error
code that should be passed as a return code from your driver routine.
\f4b_error\f1 and \f4b_oerror\f1 is set in conjunction with the
\f4B_ERROR\f1 flag (set by the operating system in the \f4b_flags\f1
member).  The error codes are described in Appendix A.
.P 
\f4b_resid\f1 indicates the number of bytes not transferred because
of an error. 
.P
\f4b_start\f1 holds the time the I/O request was started.
.P
\f4b_proc\f1 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 \f4b_un\f1 member.
.P
\f4b_pages\f1 contains a pointer to the \f4page\f1 structure list
used in a paged I/O operation. 
.P
\f4b_bufsize\fP contains the size of the allocated buffer.
.P
\f4(*b_iodone)\fP identifies a specific \f4biodone\fP routine to be
called by the driver when the I/O is complete.
.P
\f4b_vp\fP identifies the vnode associated with the block.
.SH SEE ALSO
.na
\f4strategy\f1(D2DK),
\f4physiock\f1(D3D),
\f4brelse\f1(D3DK),
\f4clrbuf\f1(D3DK),
\f4iovec\f1(D4DK),
\f4uio\f1(D4DK)
.ad
