strategy(D2)
strategy - perform block I/O
As shipped in IRIX 6.5.15. Unchanged since IRIX 6.5.
NAME strategy - perform block I/O SYNOPSIS #include <sys/types.h> #include <sys/buf.h> #include <sys/errno.h> #include <sys/ddi.h> int prefixstrategy(struct buf *bp); Arguments bp Pointer to the buffer header structure. DESCRIPTION The strategy routine is called by the kernel to read and write blocks of data on the block device. strategy may also be called directly or indirectly (via a call to the physiock(D3) function) to support the raw character interface of a block device from read(D2), write(D2) or ioctl(D2). The strategy routine's responsibility is to set up and initiate the data transfer. Return Values Ignored. Errors are returned by using the bioerror(D3) function to mark the buffer as being in error. On systems where the bioerror function is not available, errors can be returned by setting the B_ERROR flag in the b_flags field of the buf structure, and setting the error number in the b_error field of the buf structure. USAGE This entry point is required in all block device drivers. Generally, the first validation test performed by the strategy routine is to see if the I/O is within the bounds of the device. If the starting block number, given by bp->b_blkno, is less than 0 or greater than the number of blocks on the device, the error number in the buffer header should be set to ENXIO, and the B_ERROR flag should be set in bp- >b_flags. If the bioerror routine is available, bioerror should be used to set the buffer error number to ENXIO. Then, the buffer should be marked done by calling biodone(D3), and the driver should return. If bp->b_blkno is equal to the number of blocks on the device and the operation is a write, indicated by the absence of the B_READ flag in bp- >b_flags (!(bp->b_flags & B_READ)), then the same action should be taken. However, if the operation is a read and bp->b_blkno is equal to the number of blocks on the device, then the driver should set bp->b_resid equal to bp->b_bcount, mark the buffer done by calling biodone, and return. This will cause the read to return 0. Once the I/O request has been validated, the strategy routine should queue the request. If there is not already a transfer under way, the I/O is started. Then the strategy routine returns. When the I/O is complete, the driver will call biodone to free the buffer and notify anyone who has called biowait(D3) to wait for the I/O to finish. There are two kinds of I/O requests passed to strategy routines: normal block I/O requests and paged-I/O requests. Normal block I/O requests are identified by the absence of the B_PAGEIO flag or the presence of the B_MAPPED in bp->b_flags. Here, the starting kernel virtual address of the data transfer will be found in bp->b_un.b_addr. Paged-I/O requests are identified by the presence of the B_PAGEIO flag in bp->b_flags. The driver has several ways to perform a paged-I/O request. If the driver wants to use virtual addresses, it can call bp_mapin(D3) to get a virtually contiguous mapping for the pages. The physical address can be obtained by calling kvtophys(D3X) for each page in the virtual address range. If the amount of data to be transferred is more than can be transferred, the driver can transfer as much as possible (if it supports partial reads and writes), and then use the bioerror function to set the buffer error number to EIO. If the bioerror function is not available, the driver should then set the B_ERROR flag, and set bp->b_resid equal to the number of bytes not transferred (if all of the data were transferred, bp- >b_resid should be set to 0). Synchronization Constraints The strategy entry point has the necessary context to sleep, but it cannot assume it is called from the same context of the process that initiated the I/O request. Furthermore, the process that initiated the I/O might not even be in existence when the strategy routine is called. REFERENCES biodone(D3), bioerror(D3), biowait(D3), bp_mapin(D3), buf(D4), devflag(D1), errnos(D5), kvtophys(D3X), physiock(D3), read(D2), write(D2)