This list did not initially receive a CC of these patches, here they
are for your viewing pleasure! Patches apply against 2.6.13-rc3-mm1.
This patch is probably the most contentious one; adding a hotswap
framework to libata to allow it to handle disk plugs/unplugs.
The design goals for this framework were as follows:
- easy, stable API.
- simplicity of design and code
- as damn near as we can get to a guarantee that we will NOT panic the
kernel if the user does something stupid, an an attempt to guarantee
correct behaviour anyways.
To meet these goals, I have many comments. The new API, as far as
driver writers see, is two functions 'ata_hotplug_plug' and
'ata_hotplug_unplug'. Respectively, these should be called when a new
disk is picked up or removed. This seems like the most logical way to
go about this.
The functions use a single shared workqueue to schedule plug and
unplug events. In the 'normal case' where a user merely plugs in or
unplugs a disk, you can trivially follow the functionality. The edge
cases all have to do with these cases: what happens when the user
really quickly plugs/unplugs disks, or has pending I/O?
You'll note at a cursory glance that we need to call an ata_bus_reset
when plugging in a disk; this means that we have to wait a bit for
everything to settle. If the user goes and unplugs the disk on us, we
need to immediately take corrective action.
As such, the 'plug' function is a little complicated.
There is also the issue of I/O (or other requests?) pending on a
device when we unplug it. Since we do not want to panic the kernel,
we need to handle them gracefully. As it stands, the SCSI layer does
this for us rather nicely, EXCEPT in the case that we have an
outstanding qc on our device, waiting for completion. This is the
explanation for the 'if (qc)' checks in various parts of the code to
kill these functions.
I must point out that I have NOT tested this on SMP systems, where we
can potentially be servicing more than one request from our request
queue. Potentially doing a plug/unplug/plug/unplug/etc. kind of
action very fast might lead us to running multiple 'plug' and 'unplug'
functions simultaneously.
I did NOT want to complicate the libata code by throwing spinlocks
around all over the place to protect against this (changing working,
existing code), instead, I have wrapped the 'plug' and 'unplug'
functions within a mutex. This should ensure no erroneous behaviour,
and still service requests in a timely fashion 99% of the time (on UP
systems, it actually makes no difference).
There are GRATUITOUS comments put in the code for you to look at to
see if my logic is flawed. Have fun!
Luke Kosewski
Human Cannonball
Net Integration Technologies
02-libata_hotswap_infrastructure-2.6.13-rc3-mm1.diff
Description: Text Data
|