Check out the new USENIX Web site. next up previous
Next: Further Details of Linux Up: Implementation Previous: Data Structures

I/O Handling

On an access, the region spanned by it is locked. This is required as the type of the stripe should not change when an access is in progress. The access is then subdivided into separate subaccesses at the stripe granularity. These are then grouped under a StageIO and issued to the underlying storage drivers. The StageIO maintains a count of the number sub I/Os. In UNIX, whenever a block I/O request completes, biodone() is called for the request in the interrupt context which results in a call to the routine pointed to by the b_iodone field of the I/O request data structure (struct buf). The count is decremented in this calling routine and when count becomes zero, the parent I/O is signalled as complete by calling biodone() on it.

In Linux, as discussed above in Section 4.2.1, we have to come up with a few workarounds for a similar effect.

I/O Interlocking is not critical for non redundant storage but for redundant storage schemes like RAID it is essential for correct operation. For RAID1, we need to interlock the I/O region as two concurrent updates can leave the two copies (the data and the mirror) out of sync.

For RAID5/cRAID5, the updates need not be overlapping either to result in wrong operation. If two update accesses come to the same stripe, they need to be serialized as both will be updating the parity (in addition to the data). In addition, in cRAID5, the interlock has to be set at the logical stripe level so that atomicity of the write is maintained in case of simultaneous accesses to the compressed stripe.

In addition, we need to make sure that the type of a logical stripe does not change when an I/O is in progress on it.


next up previous
Next: Further Details of Linux Up: Implementation Previous: Data Structures
Dr K Gopinath
2000-04-25