From 75b8e04bbf01bdd5c42a1d8ac54abf757196ce49 Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Wed, 24 Sep 2014 17:47:18 +0200 Subject: dm raid: add discard support for RAID levels 1 and 10 Discard support is not enabled for RAID levels 4, 5, and 6 at this time due to concerns about unreliable discard_zeroes_data support on some hardware. Otherwise, discards could cause stripe data corruption (classic example of bad apples spoiling the bunch). Signed-off-by: Heinz Mauelshagen Signed-off-by: Mike Snitzer --- drivers/md/dm-raid.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'drivers/md') diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 4880b69e2e9e..030e2d6bc261 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2010-2011 Neil Brown - * Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2014 Red Hat, Inc. All rights reserved. * * This file is released under the GPL. */ @@ -1149,6 +1149,27 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) return 0; } +/* + * Enable/disable discard support on RAID set depending on RAID level. + */ +static void configure_discard_support(struct dm_target *ti, struct raid_set *rs) +{ + /* Assume discards not supported until after checks below. */ + ti->discards_supported = false; + + /* RAID level 4,5,6 require discard_zeroes_data for data integrity! */ + if (rs->md.level == 4 || rs->md.level == 5 || rs->md.level == 6) + return; /* discard_zeroes_data cannot be trusted as reliable */ + + ti->discards_supported = true; + + /* + * RAID1 and RAID10 personalities require bio splitting, + */ + ti->split_discard_bios = true; + ti->num_discard_bios = 1; +} + /* * Construct a RAID4/5/6 mapping: * Args: @@ -1231,6 +1252,11 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) ti->private = rs; ti->num_flush_bios = 1; + /* + * Disable/enable discard support on RAID set. + */ + configure_discard_support(ti, rs); + mutex_lock(&rs->md.reconfig_mutex); ret = md_run(&rs->md); rs->md.in_sync = 0; /* Assume already marked dirty */ @@ -1652,7 +1678,7 @@ static void raid_resume(struct dm_target *ti) static struct target_type raid_target = { .name = "raid", - .version = {1, 5, 2}, + .version = {1, 6, 0}, .module = THIS_MODULE, .ctr = raid_ctr, .dtr = raid_dtr, -- cgit v1.2.3