Skip to content

Commit

Permalink
dm: disable WRITE SAME if it fails
Browse files Browse the repository at this point in the history
Add DM core support for disabling WRITE SAME on first failure to both
request-based and bio-based targets.  The need to disable WRITE SAME
stems from SCSI enabling it by default but then disabling it when it
fails.  When SCSI does this it returns "permanent target failure, do
not retry" using -EREMOTEIO.  Update DM core to only disable WRITE SAME
on failure if the returned error is -EREMOTEIO.

Commit f84cb8a ("dm mpath: disable WRITE SAME if it fails")
implemented multipath specific disabling of WRITE SAME if it fails.
However, as that commit detailed, the multipath-only solution doesn't go
far enough if bio-based DM targets are stacked ontop of the
request-based dm-multipath target (as is commonly done using dm-linear
to support partitions on multipath devices, via kpartx).

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Acked-by: Martin K. Petersen <martin.petersen@oracle.com>
Tested-by: Alex Chen <alex.chen@huawei.com>
  • Loading branch information
Mike Snitzer committed Jun 4, 2014
1 parent 989f26f commit 7eee4ae
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 10 deletions.
11 changes: 1 addition & 10 deletions drivers/md/dm-mpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -1242,17 +1242,8 @@ static int do_end_io(struct multipath *m, struct request *clone,
if (!error && !clone->errors)
return 0; /* I/O complete */

if (noretry_error(error)) {
if ((clone->cmd_flags & REQ_WRITE_SAME) &&
!clone->q->limits.max_write_same_sectors) {
struct queue_limits *limits;

/* device doesn't really support WRITE SAME, disable it */
limits = dm_get_queue_limits(dm_table_get_md(m->ti->table));
limits->max_write_same_sectors = 0;
}
if (noretry_error(error))
return error;
}

if (mpio->pgpath)
fail_path(mpio->pgpath);
Expand Down
16 changes: 16 additions & 0 deletions drivers/md/dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,14 @@ static void dec_pending(struct dm_io *io, int error)
}
}

static void disable_write_same(struct mapped_device *md)
{
struct queue_limits *limits = dm_get_queue_limits(md);

/* device doesn't really support WRITE SAME, disable it */
limits->max_write_same_sectors = 0;
}

static void clone_endio(struct bio *bio, int error)
{
int r = 0;
Expand Down Expand Up @@ -783,6 +791,10 @@ static void clone_endio(struct bio *bio, int error)
}
}

if (unlikely(r == -EREMOTEIO && (bio->bi_rw & REQ_WRITE_SAME) &&
!bdev_get_queue(bio->bi_bdev)->limits.max_write_same_sectors))
disable_write_same(md);

free_tio(md, tio);
dec_pending(io, error);
}
Expand Down Expand Up @@ -977,6 +989,10 @@ static void dm_done(struct request *clone, int error, bool mapped)
r = rq_end_io(tio->ti, clone, error, &tio->info);
}

if (unlikely(r == -EREMOTEIO && (clone->cmd_flags & REQ_WRITE_SAME) &&
!clone->q->limits.max_write_same_sectors))
disable_write_same(tio->md);

if (r <= 0)
/* The target wants to complete the I/O */
dm_end_request(clone, r);
Expand Down

0 comments on commit 7eee4ae

Please sign in to comment.