From patchwork Sat Dec 12 08:41:06 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongsheng Yang X-Patchwork-Id: 555972 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 954141402BF for ; Sat, 12 Dec 2015 19:51:27 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1a7fsV-0000bX-1n; Sat, 12 Dec 2015 08:50:07 +0000 Received: from [59.151.112.132] (helo=heian.cn.fujitsu.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1a7fsO-00008L-OR for linux-mtd@lists.infradead.org; Sat, 12 Dec 2015 08:50:04 +0000 X-IronPort-AV: E=Sophos;i="5.20,346,1444665600"; d="scan'208";a="1490033" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 12 Dec 2015 16:48:47 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id 199FF4092567; Sat, 12 Dec 2015 16:48:43 +0800 (CST) Received: from yds-PC.g08.fujitsu.local (10.167.226.66) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.181.6; Sat, 12 Dec 2015 16:48:42 +0800 From: Dongsheng Yang To: , , , , , , , , , , , , , , Subject: [PATCH v2 6/7] mtd: mtd_raid: introduce raid1 implementation Date: Sat, 12 Dec 2015 16:41:06 +0800 Message-ID: <1449909667-7759-7-git-send-email-yangds.fnst@cn.fujitsu.com> X-Mailer: git-send-email 1.8.4.2 In-Reply-To: <1449909667-7759-1-git-send-email-yangds.fnst@cn.fujitsu.com> References: <1449909667-7759-1-git-send-email-yangds.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.226.66] X-yoursite-MailScanner-Information: Please contact the ISP for more information X-yoursite-MailScanner-ID: 199FF4092567.A52CB X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: yangds.fnst@cn.fujitsu.com X-Spam-Status: No X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151212_005003_775369_034B59F3 X-CRM114-Status: GOOD ( 14.65 ) X-Spam-Score: -1.1 (-) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-1.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.8 RDNS_NONE Delivered to internal network by a host with no rDNS X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dongsheng Yang Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org This is implementation of raid1, the main work of it is to mapping logical address to physical address and mapping physical address to logical address. That would be used when we meet an error in reading and want to find the mirror in raid1. Signed-off-by: Dongsheng Yang --- drivers/mtd/mtd_raid/raid1.c | 156 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 drivers/mtd/mtd_raid/raid1.c diff --git a/drivers/mtd/mtd_raid/raid1.c b/drivers/mtd/mtd_raid/raid1.c new file mode 100644 index 0000000..198725c --- /dev/null +++ b/drivers/mtd/mtd_raid/raid1.c @@ -0,0 +1,156 @@ +/* + * This file is part of MTD RAID. + * + * Copyright (C) 2015 Dongsheng Yang. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Dongsheng Yang + */ + +/** + * This file implement raid1. + * RAID1: + * + * Flash A: + * ------------------------------ + * | A1 | A2 | ... | An | + * ------------------------------ + * Flash B: + * ------------------------------ + * | B1 | B2 | ... | Bn | + * ------------------------------ + * Flash C: + * ------------------------------ + * | C1 | C2 | ... | Cn | + * ------------------------------ + * + * RAID1: + * ------------------------------ + * | A1 | A2 | ... | An | + * ------------------------------ + * ------------------------------ + * | B1 | B2 | ... | Bn | Mirror + * ------------------------------ + * ------------------------------ + * | C1 | C2 | ... | Cn | Mirror + * ------------------------------ + * + * C1 = B1 = A1. They store same data in three different flashes. + * + * Detail to see: + * https://en.wikipedia.org/wiki/Standard_RAID_levels + */ + +#include +#include + +#include "mtd_raid.h" + +static int raid1_logical_to_physical(struct mtd_raid *raid, loff_t from, size_t len, int copy_num, + int *devid, loff_t *subdev_off, size_t *size) +{ + *devid = copy_num; + *subdev_off = from; + *size = len; + + return 0; +} + +/** + * This function will convert the physical address to logical address. + */ +static int raid1_physical_to_logical(struct mtd_raid *raid, int devid, loff_t subdev_off, size_t size, + loff_t *from, size_t *len) +{ + *from = subdev_off; + *len = size; + + return 0; +} + +struct mtd_raid *mtd_raid1_create(int dev_count, size_t substripe_size) +{ + struct mtd_raid1 *raid1 = NULL; + struct mtd_raid *raid = NULL; + + raid1 = kzalloc(sizeof(struct mtd_raid1) + sizeof(struct mtd_raid_dev) * dev_count, GFP_KERNEL); + if (!raid1) + goto out; + + raid = &raid1->raid; + raid->raid_level = MTD_RAID_LEVEL_RAID1; + raid->ops = &mtd_raid1_ops; + raid->ncopies = dev_count; + raid->npebs_per_leb = 1; + + return &raid1->raid; +out: + return NULL; +} + +static int raid1_init(struct mtd_raid *raid, + int dev_count, size_t substripe_size) +{ + int ret = 0; + int i = 0; + int raid_id = 0; + struct mtd_info *mtd = &raid->mtd; + struct mtd_info *subdev = raid->devs[0].mtd; + + raid_id = mtd_raid_list_register(MTD_RAID_LEVEL_RAID1, raid); + sprintf(raid->name, "mtd1-%d", raid_id); + mtd->name = raid->name; + + /** + * size and erasesize are same with subdev. + */ + mtd->size = subdev->size; + mtd->erasesize = subdev->erasesize; + for (i = 0; i < dev_count; i++) { + subdev = raid->devs[i].mtd; + if (mtd->size != subdev->size) { + pr_err("Incompatible size on \"%s\"", + subdev->name); + ret = -EINVAL; + goto out; + } + + if (mtd->erasesize != subdev->erasesize) { + pr_err("Incompatible erasesize on \"%s\"", + subdev->name); + ret = -EINVAL; + goto out; + } + } + +out: + return ret; +} + + +void raid1_destroy(struct mtd_raid *mtd_raid) +{ + struct mtd_raid1 *raid1 = MTD_RAID_RAID1(mtd_raid); + + mtd_raid_list_unregister(&raid1->raid); + kfree(raid1); +} + +const struct mtd_raid_operations mtd_raid1_ops = { + .init = raid1_init, + .destroy = raid1_destroy, + .logical_to_physical = raid1_logical_to_physical, + .physical_to_logical = raid1_physical_to_logical, +};