Commit d2d9e9edf939ea938921f0e6c7e3151a308d4411
Committed by
Greg Kroah-Hartman
1 parent
0e8422433e
md/raid5: fix another livelock caused by non-aligned writes.
commit b1b02fe97f75b12ab34b2303bfd4e3526d903a58 upstream. If a non-page-aligned write is destined for a device which is missing/faulty, we can deadlock. As the target device is missing, a read-modify-write cycle is not possible. As the write is not for a full-page, a recontruct-write cycle is not possible. This should be handled by logic in fetch_block() which notices there is a non-R5_OVERWRITE write to a missing device, and so loads all blocks. However since commit 67f455486d2ea2, that code requires STRIPE_PREREAD_ACTIVE before it will active, and those circumstances never set STRIPE_PREREAD_ACTIVE. So: in handle_stripe_dirtying, if neither rmw or rcw was possible, set STRIPE_DELAYED, which will cause STRIPE_PREREAD_ACTIVE be set after a suitable delay. Fixes: 67f455486d2ea20b2d94d6adf5b9b783d079e321 Reported-by: Mikulas Patocka <mpatocka@redhat.com> Tested-by: Heinz Mauelshagen <heinzm@redhat.com> Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 1 changed file with 5 additions and 0 deletions Side-by-side Diff
drivers/md/raid5.c
... | ... | @@ -3195,6 +3195,11 @@ |
3195 | 3195 | (unsigned long long)sh->sector, |
3196 | 3196 | rcw, qread, test_bit(STRIPE_DELAYED, &sh->state)); |
3197 | 3197 | } |
3198 | + | |
3199 | + if (rcw > disks && rmw > disks && | |
3200 | + !test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) | |
3201 | + set_bit(STRIPE_DELAYED, &sh->state); | |
3202 | + | |
3198 | 3203 | /* now if nothing is locked, and if we have enough data, |
3199 | 3204 | * we can start a write request |
3200 | 3205 | */ |