]> asedeno.scripts.mit.edu Git - linux.git/commit
md/raid1: simplify handle_read_error().
authorNeilBrown <neilb@suse.com>
Wed, 5 Apr 2017 04:05:50 +0000 (14:05 +1000)
committerShaohua Li <shli@fb.com>
Tue, 11 Apr 2017 17:10:20 +0000 (10:10 -0700)
commit689389a06ce79fdced85b5115717f71c71e623e0
treebeacf4e145c55913542aea4f83188bec206d9221
parent50512625da06c41517cb596f51b923ce15f401a4
md/raid1: simplify handle_read_error().

handle_read_error() duplicates a lot of the work that raid1_read_request()
does, so it makes sense to just use that function.
This doesn't quite work as handle_read_error() relies on the same r1bio
being re-used so that, in the case of a read-only array, setting
IO_BLOCKED in r1bio->bios[] ensures read_balance() won't re-use
that device.
So we need to allow a r1bio to be passed to raid1_read_request(), and to
have that function mostly initialise the r1bio, but leave the bios[]
array untouched.

Two parts of handle_read_error() that need to be preserved are the warning
message it prints, so they are conditionally added to raid1_read_request().

Note that this highlights a minor bug on alloc_r1bio().  It doesn't
initalise the bios[] array, so it is possible that old content is there,
which might cause read_balance() to ignore some devices with no good reason.

With this change, we no longer need inc_pending(), or the sectors_handled
arg to alloc_r1bio().

As handle_read_error() is called from raid1d() and allocates memory,
there is tiny chance of a deadlock.  All element of various pools
could be queued waiting for raid1 to handle them, and there may be no
extra memory free.
Achieving guaranteed forward progress would probably require a second
thread and another mempool.  Instead of that complexity, add
__GFP_HIGH to any allocations when read1_read_request() is called
from raid1d.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Shaohua Li <shli@fb.com>
drivers/md/raid1.c