lkml.org 
[lkml]   [2018]   [Apr]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.9 080/293] Revert "dm mirror: use all available legs on multiple failures"
    Date
    From: Mike Snitzer <snitzer@redhat.com>

    [ Upstream commit cd15fb64ee56192760ad5c1e2ad97a65e735b18b ]

    This reverts commit 12a7cf5ba6c776a2621d8972c7d42e8d3d959d20.

    This commit apparently attempted to fix an issue that didn't really
    exist, furthermore: this commit is the source of deadlocks and crashes
    seen in multiple cases related to failing the primary mirror dev while
    syncing.

    Reported-by: Jonathan Brassow <jbrassow@redhat.com>
    Signed-off-by: Mike Snitzer <snitzer@redhat.com>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    drivers/md/dm-raid1.c | 21 +++++++++++++++++++--
    1 file changed, 19 insertions(+), 2 deletions(-)

    diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
    index 9a8b71067c6e..7a6254d54baf 100644
    --- a/drivers/md/dm-raid1.c
    +++ b/drivers/md/dm-raid1.c
    @@ -145,6 +145,7 @@ static void dispatch_bios(void *context, struct bio_list *bio_list)

    struct dm_raid1_bio_record {
    struct mirror *m;
    + /* if details->bi_bdev == NULL, details were not saved */
    struct dm_bio_details details;
    region_t write_region;
    };
    @@ -1199,6 +1200,8 @@ static int mirror_map(struct dm_target *ti, struct bio *bio)
    struct dm_raid1_bio_record *bio_record =
    dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));

    + bio_record->details.bi_bdev = NULL;
    +
    if (rw == WRITE) {
    /* Save region for mirror_end_io() handler */
    bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio);
    @@ -1257,12 +1260,22 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
    }

    if (error == -EOPNOTSUPP)
    - return error;
    + goto out;

    if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD))
    - return error;
    + goto out;

    if (unlikely(error)) {
    + if (!bio_record->details.bi_bdev) {
    + /*
    + * There wasn't enough memory to record necessary
    + * information for a retry or there was no other
    + * mirror in-sync.
    + */
    + DMERR_LIMIT("Mirror read failed.");
    + return -EIO;
    + }
    +
    m = bio_record->m;

    DMERR("Mirror read failed from %s. Trying alternative device.",
    @@ -1278,6 +1291,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
    bd = &bio_record->details;

    dm_bio_restore(bd, bio);
    + bio_record->details.bi_bdev = NULL;
    bio->bi_error = 0;

    queue_bio(ms, bio, rw);
    @@ -1286,6 +1300,9 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
    DMERR("All replicated volumes dead, failing I/O");
    }

    +out:
    + bio_record->details.bi_bdev = NULL;
    +
    return error;
    }

    --
    2.15.1
    \
     
     \ /
      Last update: 2018-04-09 04:30    [W:4.080 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site