Linus, below is a patch for 2.4.0-test that adds documentation for ll_rw_block and generic_make_request. It also corrects a type error in a printk call. I would really like to change a couple of names in the file: "generic_make_request" would sound much better as "raw_rw_block". that would highlight it's similarity to ll_rw_block, and would remove the "generic" which seems to imply that it is possible to replace it with a specific_make_request - which is wrong. also "__make_request" would sound much better as elevator_make_request, as that is more descriptive of what it does. Also __foo() normally is a special (e.g. no locking) case of foo(), but that is not the case here. Would you accept such as patch at this stage? NeilBrown --- drivers/block/ll_rw_blk.c 2000/12/03 23:59:07 1.1 +++ drivers/block/ll_rw_blk.c 2000/12/04 00:17:34 @@ -262,13 +262,18 @@ * * Description: * The normal way for &struct buffer_heads to be passed to a device driver - * it to collect into requests on a request queue, and allow the device - * driver to select requests off that queue when it is ready. This works - * well for many block devices. However some block devices (typically - * virtual devices such as md or lvm) do not benefit from the processes on + * is for them to be collected into requests on a request queue, and then to + * allow the device driver to select requests off that queue when it is ready. + * This works well for many block devices. However some block devices (typically + * virtual devices such as md or lvm) do not benefit from the processing on * the request queue, and are served best by having the requests passed * directly to them. This can be achieved by providing a function to * blk_queue_make_request(). + * + * Caveat: + * The driver that does this *must* be able to deal appropriately with + * buffers in "highmemory", either by calling bh_kmap() to get a kernel mapping, + * to by calling create_bounce() to create a buffer in normal memory. **/ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn) @@ -831,6 +836,40 @@ return 0; } +/** + * generic_make_request: hand a buffer head to it's device driver for I/O + * @rw: READ, WRITE, or READA - what sort of I/O is desired. + * @bh: The buffer head describing the location in memory and on the device. + * + * generic_make_request() is used to make I/O requests of block + * devices. It is passed a &struct buffer_head and a &rw value. The + * %READ and %WRITE options are (hopefully) obvious in meaning. The + * %READA value means that a read is required, but that the driver is + * free to fail the request if, for example, it cannot get needed + * resources immediately. + * + * generic_make_request() does not return any status. The + * success/failure status of the request, along with notification of + * completion, is delivered asynchronously through the bh->b_end_io + * function described (one day) else where. + * + * The caller of generic_make_request must make sure that b_page, + * b_addr, b_size are set to describe the memory buffer, that b_rdev + * and b_rsector are set to describe the device address, and the + * b_end_io and optionally b_private are set to describe how + * completion notification should be signaled. BH_Mapped should also + * be set (to confirm that b_dev and b_blocknr are valid). + * + * generic_make_request and the drivers it calls may use b_reqnext, + * and may change b_rdev and b_rsector. So the values of these fields + * should NOT be depended on after the call to generic_make_request. + * Because of this, the caller should record the device address + * information in b_dev and b_blocknr. + * + * Apart from those fields mentioned above, no other fields, and in + * particular, no other flags, are changed by generic_make_request or + * any lower level drivers. + * */ void generic_make_request (int rw, struct buffer_head * bh) { int major = MAJOR(bh->b_rdev); @@ -851,7 +890,7 @@ when mounting a device. */ printk(KERN_INFO "attempt to access beyond end of device\n"); - printk(KERN_INFO "%s: rw=%d, want=%d, limit=%d\n", + printk(KERN_INFO "%s: rw=%d, want=%ld, limit=%d\n", kdevname(bh->b_rdev), rw, (sector + count)>>1, blk_size[major][MINOR(bh->b_rdev)]); @@ -883,9 +922,39 @@ while (q->make_request_fn(q, rw, bh)); } -/* This function can be used to request a number of buffers from a block - device. Currently the only restriction is that all buffers must belong to - the same device */ +/** + * ll_rw_block: low-level access to block devices + * @rw: whether to %READ or %WRITE or maybe %READA (readahead) + * @nr: number of &struct buffer_heads in the array + * @bhs: array of pointers to &struct buffer_head + * + * ll_rw_block() takes an array of pointers to &struct buffer_heads, + * and requests an I/O operation on them, either a %READ or a %WRITE. + * The third %READA option is described in the documentation for + * generic_make_request() which ll_rw_block() calls. + * + * This function provides extra functionality that is not in + * generic_make_request() that is relevant to buffers in the buffer + * cache or page cache. In particular it drops any buffer that it + * cannot get a lock on (with the BH_Lock state bit), any buffer that + * appears to be clean when doing a write request, and any buffer that + * appears to be up-to-date when doing read request. Further it marks + * as clean buffers that are processed for writing (the buffer cache + * wont assume that they are actually clean until the buffer gets + * unlocked). + * + * ll_rw_block sets the b_rdev and b_rsector for generic_make_request + * based on the values in b_dev and b_blocknr. It assumes that + * b_blocknr is in multiples of b_size bytes (b_rsector must always be + * in multiples of 512bytes). + * + * The comments in the documentation for generic_make_request() about + * what fields need to be set up apply to ll_rw_block as well. + * + * Caveat: + * All of the buffers must be for the same device, and must also be + * of the current approved size for the device. + */ void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]) { - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] Please read the FAQ at http://www.tux.org/lkml/