Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+17 -10
+1 -10
drivers/md/dm-mpath.c
··· 1242 1242 if (!error && !clone->errors) 1243 1243 return 0; /* I/O complete */ 1244 1244 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 - } 1245 + if (noretry_error(error)) 1254 1246 return error; 1255 - } 1256 1247 1257 1248 if (mpio->pgpath) 1258 1249 fail_path(mpio->pgpath);
+16
drivers/md/dm.c
··· 755 755 } 756 756 } 757 757 758 + static 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 + 758 766 static void clone_endio(struct bio *bio, int error) 759 767 { 760 768 int r = 0; ··· 790 782 BUG(); 791 783 } 792 784 } 785 + 786 + if (unlikely(r == -EREMOTEIO && (bio->bi_rw & REQ_WRITE_SAME) && 787 + !bdev_get_queue(bio->bi_bdev)->limits.max_write_same_sectors)) 788 + disable_write_same(md); 793 789 794 790 free_tio(md, tio); 795 791 dec_pending(io, error); ··· 988 976 if (mapped && rq_end_io) 989 977 r = rq_end_io(tio->ti, clone, error, &tio->info); 990 978 } 979 + 980 + if (unlikely(r == -EREMOTEIO && (clone->cmd_flags & REQ_WRITE_SAME) && 981 + !clone->q->limits.max_write_same_sectors)) 982 + disable_write_same(tio->md); 991 983 992 984 if (r <= 0) 993 985 /* The target wants to complete the I/O */