• NeilBrown's avatar
    md/raid1: simplify handle_read_error(). · 689389a0
    NeilBrown authored
    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: default avatarNeilBrown <neilb@suse.com>
    Signed-off-by: default avatarShaohua Li <shli@fb.com>
    689389a0
raid1.c 91.8 KB