aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2014-06-02 15:50:06 -0400
committerMike Snitzer <snitzer@redhat.com>2014-06-04 09:45:52 -0400
commit7eee4ae2dbb2be0a15a4406718806e48b18ba831 (patch)
tree4e81ea5fb259ce57ad989428dba31d503d95f342 /drivers/md
parent989f26f5ad308f40a95f280bf9cd75e558d4f18d (diff)
dm: disable WRITE SAME if it fails
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 f84cb8a4 ("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>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-mpath.c11
-rw-r--r--drivers/md/dm.c16
2 files changed, 17 insertions, 10 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index ebfa411d1a7d..3f6fd9d33ba3 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -1242,17 +1242,8 @@ static int do_end_io(struct multipath *m, struct request *clone,
1242 if (!error && !clone->errors) 1242 if (!error && !clone->errors)
1243 return 0; /* I/O complete */ 1243 return 0; /* I/O complete */
1244 1244
1245 if (noretry_error(error)) { 1245 if (noretry_error(error))
1246 if ((clone->cmd_flags & REQ_WRITE_SAME) &&
1247 !clone->q->limits.max_write_same_sectors) {
1248 struct queue_limits *limits;
1249
1250 /* device doesn't really support WRITE SAME, disable it */
1251 limits = dm_get_queue_limits(dm_table_get_md(m->ti->table));
1252 limits->max_write_same_sectors = 0;
1253 }
1254 return error; 1246 return error;
1255 }
1256 1247
1257 if (mpio->pgpath) 1248 if (mpio->pgpath)
1258 fail_path(mpio->pgpath); 1249 fail_path(mpio->pgpath);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 97940fc8c302..3234a753a80d 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -755,6 +755,14 @@ static void dec_pending(struct dm_io *io, int error)
755 } 755 }
756} 756}
757 757
758static void disable_write_same(struct mapped_device *md)
759{
760 struct queue_limits *limits = dm_get_queue_limits(md);
761
762 /* device doesn't really support WRITE SAME, disable it */
763 limits->max_write_same_sectors = 0;
764}
765
758static void clone_endio(struct bio *bio, int error) 766static void clone_endio(struct bio *bio, int error)
759{ 767{
760 int r = 0; 768 int r = 0;
@@ -783,6 +791,10 @@ static void clone_endio(struct bio *bio, int error)
783 } 791 }
784 } 792 }
785 793
794 if (unlikely(r == -EREMOTEIO && (bio->bi_rw & REQ_WRITE_SAME) &&
795 !bdev_get_queue(bio->bi_bdev)->limits.max_write_same_sectors))
796 disable_write_same(md);
797
786 free_tio(md, tio); 798 free_tio(md, tio);
787 dec_pending(io, error); 799 dec_pending(io, error);
788} 800}
@@ -977,6 +989,10 @@ static void dm_done(struct request *clone, int error, bool mapped)
977 r = rq_end_io(tio->ti, clone, error, &tio->info); 989 r = rq_end_io(tio->ti, clone, error, &tio->info);
978 } 990 }
979 991
992 if (unlikely(r == -EREMOTEIO && (clone->cmd_flags & REQ_WRITE_SAME) &&
993 !clone->q->limits.max_write_same_sectors))
994 disable_write_same(tio->md);
995
980 if (r <= 0) 996 if (r <= 0)
981 /* The target wants to complete the I/O */ 997 /* The target wants to complete the I/O */
982 dm_end_request(clone, r); 998 dm_end_request(clone, r);