Skip to content

Commit

Permalink
md/raid1,5,10: Disable WRITE SAME until a recovery strategy is in place
Browse files Browse the repository at this point in the history
There are cases where the kernel will believe that the WRITE SAME
command is supported by a block device which does not, in fact,
support WRITE SAME.  This currently happens for SATA drivers behind a
SAS controller, but there are probably a hundred other ways that can
happen, including drive firmware bugs.

After receiving an error for WRITE SAME the block layer will retry the
request as a plain write of zeroes, but mdraid will consider the
failure as fatal and consider the drive failed.  This has the effect
that all the mirrors containing a specific set of data are each
offlined in very rapid succession resulting in data loss.

However, just bouncing the request back up to the block layer isn't
ideal either, because the whole initial request-retry sequence should
be inside the write bitmap fence, which probably means that md needs
to do its own conversion of WRITE SAME to write zero.

Until the failure scenario has been sorted out, disable WRITE SAME for
raid1, raid5, and raid10.

[neilb: added raid5]

This patch is appropriate for any -stable since 3.7 when write_same
support was added.

Cc: stable@vger.kernel.org
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
  • Loading branch information
H. Peter Anvin authored and NeilBrown committed Jun 13, 2013
1 parent e2d5992 commit 5026d7a
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 5 deletions.
4 changes: 2 additions & 2 deletions drivers/md/raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -2837,8 +2837,8 @@ static int run(struct mddev *mddev)
return PTR_ERR(conf);

if (mddev->queue)
blk_queue_max_write_same_sectors(mddev->queue,
mddev->chunk_sectors);
blk_queue_max_write_same_sectors(mddev->queue, 0);

rdev_for_each(rdev, mddev) {
if (!mddev->gendisk)
continue;
Expand Down
3 changes: 1 addition & 2 deletions drivers/md/raid10.c
Original file line number Diff line number Diff line change
Expand Up @@ -3651,8 +3651,7 @@ static int run(struct mddev *mddev)
if (mddev->queue) {
blk_queue_max_discard_sectors(mddev->queue,
mddev->chunk_sectors);
blk_queue_max_write_same_sectors(mddev->queue,
mddev->chunk_sectors);
blk_queue_max_write_same_sectors(mddev->queue, 0);
blk_queue_io_min(mddev->queue, chunk_size);
if (conf->geo.raid_disks % conf->geo.near_copies)
blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks);
Expand Down
4 changes: 3 additions & 1 deletion drivers/md/raid5.c
Original file line number Diff line number Diff line change
Expand Up @@ -5465,7 +5465,7 @@ static int run(struct mddev *mddev)
if (mddev->major_version == 0 &&
mddev->minor_version > 90)
rdev->recovery_offset = reshape_offset;

if (rdev->recovery_offset < reshape_offset) {
/* We need to check old and new layout */
if (!only_parity(rdev->raid_disk,
Expand Down Expand Up @@ -5588,6 +5588,8 @@ static int run(struct mddev *mddev)
*/
mddev->queue->limits.discard_zeroes_data = 0;

blk_queue_max_write_same_sectors(mddev->queue, 0);

rdev_for_each(rdev, mddev) {
disk_stack_limits(mddev->gendisk, rdev->bdev,
rdev->data_offset << 9);
Expand Down

0 comments on commit 5026d7a

Please sign in to comment.