aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShaohua Li <shli@fb.com>2017-02-13 19:21:49 -0500
committerShaohua Li <shli@fb.com>2017-02-13 22:24:16 -0500
commit26483819f89c5cf9d27620d70c95afeeeb9bece5 (patch)
treec6bc82084038c13c7c694062b4092a1eb8485abe
parente33fbb9cc73d6502e69eaf1c178e0c39059763ea (diff)
md: disable WRITE SAME if it fails in underlayer disks
This makes md do the same thing as dm for write same IO failure. Please see 7eee4ae(dm: disable WRITE SAME if it fails) for details why we need this. We did a little bit different than dm. Instead of disabling writesame in the first IO error, we disable it till next writesame IO coming after the first IO error. This way we don't need to clone a bio. Also reported here: https://bugzilla.kernel.org/show_bug.cgi?id=118581 Suggested-by: NeilBrown <neilb@suse.com> Acked-by: NeilBrown <neilb@suse.com> Signed-off-by: Shaohua Li <shli@fb.com>
-rw-r--r--drivers/md/linear.c1
-rw-r--r--drivers/md/md.h7
-rw-r--r--drivers/md/multipath.c1
-rw-r--r--drivers/md/raid0.c1
4 files changed, 10 insertions, 0 deletions
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 26a73b2002cf..789008bc94ff 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -291,6 +291,7 @@ static void linear_make_request(struct mddev *mddev, struct bio *bio)
291 trace_block_bio_remap(bdev_get_queue(split->bi_bdev), 291 trace_block_bio_remap(bdev_get_queue(split->bi_bdev),
292 split, disk_devt(mddev->gendisk), 292 split, disk_devt(mddev->gendisk),
293 bio_sector); 293 bio_sector);
294 mddev_check_writesame(mddev, split);
294 generic_make_request(split); 295 generic_make_request(split);
295 } 296 }
296 } while (split != bio); 297 } while (split != bio);
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 2a514036a83d..42f8398181a8 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -710,4 +710,11 @@ static inline void mddev_clear_unsupported_flags(struct mddev *mddev,
710{ 710{
711 mddev->flags &= ~unsupported_flags; 711 mddev->flags &= ~unsupported_flags;
712} 712}
713
714static inline void mddev_check_writesame(struct mddev *mddev, struct bio *bio)
715{
716 if (bio_op(bio) == REQ_OP_WRITE_SAME &&
717 !bdev_get_queue(bio->bi_bdev)->limits.max_write_same_sectors)
718 mddev->queue->limits.max_write_same_sectors = 0;
719}
713#endif /* _MD_MD_H */ 720#endif /* _MD_MD_H */
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index aa8c4e5c1ee2..065fe2823285 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -138,6 +138,7 @@ static void multipath_make_request(struct mddev *mddev, struct bio * bio)
138 mp_bh->bio.bi_opf |= REQ_FAILFAST_TRANSPORT; 138 mp_bh->bio.bi_opf |= REQ_FAILFAST_TRANSPORT;
139 mp_bh->bio.bi_end_io = multipath_end_request; 139 mp_bh->bio.bi_end_io = multipath_end_request;
140 mp_bh->bio.bi_private = mp_bh; 140 mp_bh->bio.bi_private = mp_bh;
141 mddev_check_writesame(mddev, &mp_bh->bio);
141 generic_make_request(&mp_bh->bio); 142 generic_make_request(&mp_bh->bio);
142 return; 143 return;
143} 144}
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 848365d474f3..b3d264452fd5 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -503,6 +503,7 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
503 trace_block_bio_remap(bdev_get_queue(split->bi_bdev), 503 trace_block_bio_remap(bdev_get_queue(split->bi_bdev),
504 split, disk_devt(mddev->gendisk), 504 split, disk_devt(mddev->gendisk),
505 bio_sector); 505 bio_sector);
506 mddev_check_writesame(mddev, split);
506 generic_make_request(split); 507 generic_make_request(split);
507 } 508 }
508 } while (split != bio); 509 } while (split != bio);