]> git.apps.os.sepia.ceph.com Git - ceph.git/commit
osd/ECBackend: only check required shards when finishing recovery reads
authorJosh Durgin <jdurgin@redhat.com>
Fri, 6 Apr 2018 06:43:13 +0000 (02:43 -0400)
committerDavid Zafman <dzafman@redhat.com>
Wed, 9 May 2018 22:41:34 +0000 (15:41 -0700)
commite9e4c42bf098ab9ae2b5d60e7d3a8f688d70e3db
treef47892695dd88787e0b2767d31c9c4947cdad861
parent952d42a7e9a429a1a26d102f333c9f532e965562
osd/ECBackend: only check required shards when finishing recovery reads

1235810c2ad08ccb7ef5946686eb2b85798f5bca allowed recovery to use
multiple passes of reads to handle EIO, but the end condition for
checking whether we finished reading requires the full data to be
decodable (this is what get_want_to_read_shards returns).

This is just a loss of efficiency normally, since when there is only
one object the subsequent read works, and grabs all the data
necessary. The crash comes from having multiple objects in the same
ReadOp - in this case the sequence of events is:

- start recovery of two objects (osd_recovery_max_single_start > 1)
- read object a shard 3
- read object b shard 3
- fail minimum_to_decode because shard 3 can't reconstruct all of object a
- re-read all of object a, marking more reads in progress
- fail minimum_to_decode because shard 3 can't reconstruct all of object b
- skip re-reading object because there are now reads in progress
- finish reading k shards of object a
- still fail minimum_to_decode for object b, so no extra data was read
- send_all_remaining_reads tries to lookup object b in ReadOp object
- crash dereferencing to_read[object b], since this was cleared after handling the original object b read reply

This patch fixes the immediate inefficiency and crash by only checking
for the missing shards that were requested, rather than the entire
object, for recovery reads.

Fixes: http://tracker.ceph.com/issues/23195 (first crash)
Signed-off-by: Josh Durgin <jdurgin@redhat.com>
(cherry picked from commit 468ad4b41010488c8d48ef65ccbebfdb4270690f)

Conflicts:
src/osd/ECBackend.cc (trivial)
qa/standalone/erasure-code/test-erasure-eio.sh
src/osd/ECBackend.cc