A new block request completion API
After a block driver has transferred one or more sectors (or failed in the attempt), it should now make a call to:
int blk_end_request(struct request *rq, int error, int nr_bytes);
Where rq is the I/O request, error is zero or a negative error code, and nr_bytes is the number of bytes successfully transferred. If blk_end_request() returns zero, the request is fully processed and the driver can forget about it. Otherwise there are still sectors to be transferred and the driver should continue with the same request.
blk_end_request() must acquire the queue lock to do its job. If the driver already holds that lock, it should call __blk_end_request() instead.
Block drivers traditionally did a number of housekeeping tasks between calls to end_that_request_first() and end_that_request_last(). These include calling add_disk_randomness() to contribute to the entropy pool, returning any tags used with the request, and removing the request from the queue. All of that stuff is now done within blk_end_request(), so drivers can forget about it. The occasional driver had to carry out other tasks between the completion of the request and its removal from the queue. For drivers with this kind of special need, there is a separate function to call:
int blk_end_request_callback(struct request *rq,
int error,
int nr_bytes,
int (drv_callback)(struct request *));
In this version, drv_callback() will be called (without the queue lock held) between the completion of the request and its final cleanup. If the callback returns a non-zero value, that final cleanup will not be done. This function will always acquire the queue lock - there is no version for drivers which have already taken that lock. In general, though, the use of the callback functionality is likely to be a sign that the driver is being tricker than it really needs to be.
This change was accompanied by a fair number of patches converting all
in-tree drivers to the new interface. The old completion functions have
been removed, so out-of-tree drivers will need updating before they will
work with 2.6.25.
| Index entries for this article | |
|---|---|
| Kernel | Block layer/Block drivers |
| Kernel | Device drivers/Block drivers |
