The bufinfo_t structure is the abstraction that describes an I/O request. The buffer corresponding to an I/O request is pointed to by args[0] in the start, done, wait-start, and wait-done probes. The bufinfo_t structure definition is as follows:
typedef struct bufinfo { int b_flags; /* flags */ size_t b_bcount; /* number of bytes */ caddr_t b_addr; /* buffer address */ uint64_t b_blkno; /* expanded block # on device */ uint64_t b_lblkno; /* block # on device */ size_t b_resid; /* # of bytes not transferred */ size_t b_bufsize; /* size of allocated buffer */ caddr_t b_iodone; /* I/O completion routine */ dev_t b_edev; /* extended device */ } bufinfo_t;
The b_flags member indicates the state of the I/O buffer, and consists of a bitwise-or of different state values. The valid state values are in Table 27–3.
Table 27–3 b_flags Values
B_DONE |
Indicates that the data transfer has completed. |
B_ERROR |
Indicates an I/O transfer error. It is set in conjunction with the b_error field. |
B_PAGEIO |
Indicates that the buffer is being used in a paged I/O request. See the description of the b_addr field for more information. |
B_PHYS |
Indicates that the buffer is being used for physical (direct) I/O to a user data area. |
B_READ |
Indicates that data is to be read from the peripheral device into main memory. |
B_WRITE |
Indicates that the data is to be transferred from main memory to the peripheral device. |
B_ASYNC |
The I/O request is asynchronous, and will not be waited upon. The wait-start and wait-done probes don't fire for asynchronous I/O requests. Note that some I/Os directed to be asynchronous might not have B_ASYNC set: the asynchronous I/O subsystem might implement the asynchronous request by having a separate worker thread perform a synchronous I/O operation. |
The b_bcount field is the number of bytes to be transferred as part of the I/O request.
The b_addr field is the virtual address of the I/O request, unless B_PAGEIO is set. The address is a kernel virtual address unless B_PHYS is set, in which case it is a user virtual address. If B_PAGEIO is set, the b_addr field contains kernel private data. Exactly one of B_PHYS and B_PAGEIO can be set, or neither flag will be set.
The b_lblkno field identifies which logical block on the device is to be accessed. The mapping from a logical block to a physical block (such as the cylinder, track, and so on) is defined by the device.
The b_resid field is set to the number of bytes not transferred because of an error.
The b_bufsize field contains the size of the allocated buffer.
The b_iodone field identifies a specific routine in the kernel that is called when the I/O is complete.
The b_error field may hold an error code returned from the driver in the event of an I/O error. b_error is set in conjunction with the B_ERROR bit set in the b_flags member.
The b_edev field contains the major and minor device numbers of the device accessed. Consumers may use the D subroutines getmajor() and getminor() to extract the major and minor device numbers from the b_edev field.