Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp57995ybp; Thu, 3 Oct 2019 10:08:32 -0700 (PDT) X-Google-Smtp-Source: APXvYqz//RoGHTo0DcflHkgoE3UJKdpIuIYIa3AH/O5gR2dGNCYOT/4iZOB5uSNcEP52CLVLXegF X-Received: by 2002:a50:f0dd:: with SMTP id a29mr10660936edm.219.1570122512125; Thu, 03 Oct 2019 10:08:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570122512; cv=none; d=google.com; s=arc-20160816; b=FOfnsqET0GIFiQC/Aztr2DnjvrK/PsrRUnSfEyi2FrfHJKdu1tiKshtPaeyxBiddB3 ZmKrpatNlQUD47Op0XxSvfNS9CTr+pUQ7MPchsgmrqQQtbgp2Ff9sZzLMtPWzJEefToj fJfQJ7LpeNJaY/wTC89HR2zVkZgAJx/iALNHyQnlWlXTisS99NcacAC3mEcdOv5lBM/l PwzQ+xA3xQrrIUNWguC9HE09es8y8Ya2Joi9Jajzitj4qwquJIq/bouWfhX2HVbtv6O/ FcwIC3/x8JWUCfXSQAZiDg7v3TaKcbPTA487RVytGcSDUuJtlsoIcGpxFiMuuqLrPU2B h95g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=EU/+keO/2f0fJFsSgcZ+l3rqpbUoOe8KGDFh/JYWKmA=; b=M2IAt2G67fF4AqPWMoT8HUXhlreGNfyQsjXHs3niBGNmqCdnAUw0QaOLU5AFRgs6WX FUaCHIeGoDAZg1tlcFJE16J2/VTulMfaYHkYa14rhHV+a7gXcTk6LMaUi9rTiJ3LhnqW N8B747/WqStyGV/377tyugCscI2oQJpzTjYIn48TADi/PaP19UWLmvI7mqnbacgkMRb4 8gRzssTMfC5Kg+4R8Rnqj1SsEjJsbjNplmAANLJTWrWiBx0ZkctOjjs7YwNAmFen1FpX VTO/anZsHL7IrGAn7XxT6hnPRAjPgVB1uWUWjO7aa8vpTC0FpWPRNNgU1SNNMkSWwHrz Pztg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nnPjpilh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q22si1546227ejx.203.2019.10.03.10.08.07; Thu, 03 Oct 2019 10:08:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nnPjpilh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404647AbfJCQh7 (ORCPT + 99 others); Thu, 3 Oct 2019 12:37:59 -0400 Received: from mail.kernel.org ([198.145.29.99]:47396 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392281AbfJCQh4 (ORCPT ); Thu, 3 Oct 2019 12:37:56 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id CFB5321783; Thu, 3 Oct 2019 16:37:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1570120675; bh=bJcao7SPBQMuapxEuG3Dz/UmDhKG/EGCDtv2S5A7S9s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nnPjpilhh+lgrgozkawVBHgHmR9BeEkfbvioNpLfmYASomKZpz6UXL83Fo5LvdRJg xrPH9pJB3zOSBnUWtq0Jb6oNmqX1hIf1ooQGmopwxEdZmCxDnMORXkadFlzDqrnnDY 3RFTvjZr0HifYCzckYlwnoUJy09kB58Vz4rZxNsE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Guoqing Jiang , NeilBrown , Song Liu , Sasha Levin Subject: [PATCH 5.2 310/313] md/raid0: avoid RAID0 data corruption due to layout confusion. Date: Thu, 3 Oct 2019 17:54:48 +0200 Message-Id: <20191003154603.729871177@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191003154533.590915454@linuxfoundation.org> References: <20191003154533.590915454@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: NeilBrown [ Upstream commit c84a1372df929033cb1a0441fb57bd3932f39ac9 ] If the drives in a RAID0 are not all the same size, the array is divided into zones. The first zone covers all drives, to the size of the smallest. The second zone covers all drives larger than the smallest, up to the size of the second smallest - etc. A change in Linux 3.14 unintentionally changed the layout for the second and subsequent zones. All the correct data is still stored, but each chunk may be assigned to a different device than in pre-3.14 kernels. This can lead to data corruption. It is not possible to determine what layout to use - it depends which kernel the data was written by. So we add a module parameter to allow the old (0) or new (1) layout to be specified, and refused to assemble an affected array if that parameter is not set. Fixes: 20d0189b1012 ("block: Introduce new bio_split()") cc: stable@vger.kernel.org (3.14+) Acked-by: Guoqing Jiang Signed-off-by: NeilBrown Signed-off-by: Song Liu Signed-off-by: Sasha Levin --- drivers/md/raid0.c | 33 ++++++++++++++++++++++++++++++++- drivers/md/raid0.h | 14 ++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index bf5cf184a260b..297bbc0f41f05 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -19,6 +19,9 @@ #include "raid0.h" #include "raid5.h" +static int default_layout = 0; +module_param(default_layout, int, 0644); + #define UNSUPPORTED_MDDEV_FLAGS \ ((1L << MD_HAS_JOURNAL) | \ (1L << MD_JOURNAL_CLEAN) | \ @@ -139,6 +142,19 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) } pr_debug("md/raid0:%s: FINAL %d zones\n", mdname(mddev), conf->nr_strip_zones); + + if (conf->nr_strip_zones == 1) { + conf->layout = RAID0_ORIG_LAYOUT; + } else if (default_layout == RAID0_ORIG_LAYOUT || + default_layout == RAID0_ALT_MULTIZONE_LAYOUT) { + conf->layout = default_layout; + } else { + pr_err("md/raid0:%s: cannot assemble multi-zone RAID0 with default_layout setting\n", + mdname(mddev)); + pr_err("md/raid0: please set raid.default_layout to 1 or 2\n"); + err = -ENOTSUPP; + goto abort; + } /* * now since we have the hard sector sizes, we can make sure * chunk size is a multiple of that sector size @@ -547,10 +563,12 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) static bool raid0_make_request(struct mddev *mddev, struct bio *bio) { + struct r0conf *conf = mddev->private; struct strip_zone *zone; struct md_rdev *tmp_dev; sector_t bio_sector; sector_t sector; + sector_t orig_sector; unsigned chunk_sects; unsigned sectors; @@ -584,8 +602,21 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio) bio = split; } + orig_sector = sector; zone = find_zone(mddev->private, §or); - tmp_dev = map_sector(mddev, zone, sector, §or); + switch (conf->layout) { + case RAID0_ORIG_LAYOUT: + tmp_dev = map_sector(mddev, zone, orig_sector, §or); + break; + case RAID0_ALT_MULTIZONE_LAYOUT: + tmp_dev = map_sector(mddev, zone, sector, §or); + break; + default: + WARN("md/raid0:%s: Invalid layout\n", mdname(mddev)); + bio_io_error(bio); + return true; + } + bio_set_dev(bio, tmp_dev->bdev); bio->bi_iter.bi_sector = sector + zone->dev_start + tmp_dev->data_offset; diff --git a/drivers/md/raid0.h b/drivers/md/raid0.h index 540e65d92642d..3816e5477db1e 100644 --- a/drivers/md/raid0.h +++ b/drivers/md/raid0.h @@ -8,11 +8,25 @@ struct strip_zone { int nb_dev; /* # of devices attached to the zone */ }; +/* Linux 3.14 (20d0189b101) made an unintended change to + * the RAID0 layout for multi-zone arrays (where devices aren't all + * the same size. + * RAID0_ORIG_LAYOUT restores the original layout + * RAID0_ALT_MULTIZONE_LAYOUT uses the altered layout + * The layouts are identical when there is only one zone (all + * devices the same size). + */ + +enum r0layout { + RAID0_ORIG_LAYOUT = 1, + RAID0_ALT_MULTIZONE_LAYOUT = 2, +}; struct r0conf { struct strip_zone *strip_zone; struct md_rdev **devlist; /* lists of rdevs, pointed to * by strip_zone->dev */ int nr_strip_zones; + enum r0layout layout; }; #endif -- 2.20.1