From patchwork Wed Sep 24 15:14:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heinz Mauelshagen X-Patchwork-Id: 4967341 X-Patchwork-Delegate: snitzer@redhat.com Return-Path: X-Original-To: patchwork-dm-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E83A99F2F0 for ; Wed, 24 Sep 2014 15:18:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 87CBA200CA for ; Wed, 24 Sep 2014 15:18:32 +0000 (UTC) Received: from mx4-phx2.redhat.com (mx4-phx2.redhat.com [209.132.183.25]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 165342017A for ; Wed, 24 Sep 2014 15:18:31 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id s8OFEc2h015084; Wed, 24 Sep 2014 11:14:38 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id s8OFEDQW007377 for ; Wed, 24 Sep 2014 11:14:13 -0400 Received: from o.ww.redhat.com (ovpn-116-72.ams2.redhat.com [10.36.116.72]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8OFEBwI021808 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 24 Sep 2014 11:14:12 -0400 Received: from o.ww.redhat.com (localhost.localdomain [127.0.0.1]) by o.ww.redhat.com (8.14.8/8.14.8) with ESMTP id s8OFEAEd018741; Wed, 24 Sep 2014 17:14:10 +0200 Received: (from mauelsha@localhost) by o.ww.redhat.com (8.14.8/8.14.8/Submit) id s8OFEAXS018740; Wed, 24 Sep 2014 17:14:10 +0200 From: heinzm@redhat.com To: dm-devel@redhat.com Date: Wed, 24 Sep 2014 17:14:09 +0200 Message-Id: <1411571650-18702-2-git-send-email-heinzm@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-loop: dm-devel@redhat.com Cc: Heinz Mauelshagen Subject: [dm-devel] [PATCH 2/3] dm-raid: add 'no_discard_passdown' table argument X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Heinz Mauelshagen Add the 'no_discard_passdown' table line argument to the target in order to be able to prohibit discards from being passed down to the legs of an array (this is in line with our other targets thin and cache). This addresses: o prohibit discards in case of _potential_ data corruptions in RAID4/5/6 (i.e. discard_zeroes_data not processing properly when RAID4/5/6 relies on zeroed data) o avoid discard processing overhead Signed-off-by: Heinz Mauelshagen --- drivers/md/dm-raid.c | 73 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 4edb2c7..a85d3cf 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -45,17 +45,18 @@ struct raid_dev { /* * Flags for rs->print_flags field. */ -#define DMPF_SYNC 0x1 -#define DMPF_NOSYNC 0x2 -#define DMPF_REBUILD 0x4 -#define DMPF_DAEMON_SLEEP 0x8 -#define DMPF_MIN_RECOVERY_RATE 0x10 -#define DMPF_MAX_RECOVERY_RATE 0x20 -#define DMPF_MAX_WRITE_BEHIND 0x40 -#define DMPF_STRIPE_CACHE 0x80 -#define DMPF_REGION_SIZE 0x100 -#define DMPF_RAID10_COPIES 0x200 -#define DMPF_RAID10_FORMAT 0x400 +#define DMPF_SYNC 0x1 +#define DMPF_NOSYNC 0x2 +#define DMPF_REBUILD 0x4 +#define DMPF_DAEMON_SLEEP 0x8 +#define DMPF_MIN_RECOVERY_RATE 0x10 +#define DMPF_MAX_RECOVERY_RATE 0x20 +#define DMPF_MAX_WRITE_BEHIND 0x40 +#define DMPF_STRIPE_CACHE 0x80 +#define DMPF_REGION_SIZE 0x100 +#define DMPF_RAID10_COPIES 0x200 +#define DMPF_RAID10_FORMAT 0x400 +#define DMPF_NO_DISCARD_PASSDOWN 0x800 struct raid_set { struct dm_target *ti; @@ -475,6 +476,10 @@ too_many: * will form the "stripe" * [[no]sync] Force or prevent recovery of the * entire array + * [no_discard_passdown] Prohibit discard passdown to the legs of the array; + * can be used in cases of bogus TRIM/UNMAP + * support on array legs (e.g. discard_zeroes_data + * flaw causing RAID4/5/6 corruption) * [rebuild ] Rebuild the drive indicated by the index * [daemon_sleep ] Time between bitmap daemon work to * clear bits @@ -559,6 +564,10 @@ static int parse_raid_params(struct raid_set *rs, char **argv, rs->print_flags |= DMPF_SYNC; continue; } + if (!strcasecmp(argv[i], "no_discard_passdown")) { + rs->print_flags |= DMPF_NO_DISCARD_PASSDOWN; + continue; + } /* The rest of the optional arguments come in key/value pairs */ if ((i + 1) >= num_raid_params) { @@ -1157,33 +1166,37 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) static void raid_check_discard(struct dm_target *ti, struct raid_set *rs) { int i; - bool discard_supported = true; + bool discard_supported, raid456; + + /* Assume not supported until after checks below. */ + ti->discards_supported = false; + + /* Assume 'discard_supported = true' unless table argument 'no_discard_passdown' given */ + discard_supported = !(rs->print_flags & DMPF_NO_DISCARD_PASSDOWN); + if (!discard_supported) + return; + /* RAID level 4,5,6 request discard_zeroes_data for data integrity! */ - bool raid1_or_10 = rs->md.level == 1 || rs->md.level == 10; - bool zeroes_data_mandatory = !raid1_or_10; + raid456 = (rs->md.level == 5 || rs->md.level == 6 || rs->md.level == 4); for (i = 0; i < rs->md.raid_disks; i++) { struct request_queue *q = bdev_get_queue(rs->dev[i].rdev.bdev); if (!q || !blk_queue_discard(q) || - (zeroes_data_mandatory && !q->limits.discard_zeroes_data)) { - discard_supported = false; - break; - } + (raid456 && !q->limits.discard_zeroes_data)) + return; } - if (discard_supported) { - ti->discards_supported = true; - /* - * raid1 and raid10 personalities require bio splitting, - * raid4/5/6 don't and process large discard bios properly. - */ - ti->split_discard_bios = raid1_or_10; - ti->num_discard_bios = 1; + /* Passed check on array legs -> enable discard */ + ti->discards_supported = true; - } else - ti->discards_supported = false; + /* + * RAID1 and RAID10 personalities require bio splitting, + * RAID0/4/5/6 don't and process large discard bios properly + */ + ti->split_discard_bios = (rs->md.level == 1 || rs->md.level == 10); + ti->num_discard_bios = 1; } /* @@ -1458,6 +1471,8 @@ static void raid_status(struct dm_target *ti, status_type_t type, DMEMIT(" sync"); if (rs->print_flags & DMPF_NOSYNC) DMEMIT(" nosync"); + if (rs->print_flags & DMPF_NO_DISCARD_PASSDOWN) + DMEMIT(" no_discard_passsown"); for (i = 0; i < rs->md.raid_disks; i++) if ((rs->print_flags & DMPF_REBUILD) && @@ -1694,7 +1709,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,