From patchwork Tue Dec 1 10:52:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongsheng Yang X-Patchwork-Id: 550781 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 65E241401DA for ; Tue, 1 Dec 2015 22:03:18 +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 1a3igO-0001tK-P0; Tue, 01 Dec 2015 11:01:16 +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 1a3igG-0001cs-Tz for linux-mtd@lists.infradead.org; Tue, 01 Dec 2015 11:01:14 +0000 X-IronPort-AV: E=Sophos;i="5.20,346,1444665600"; d="scan'208";a="1035780" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 01 Dec 2015 19:00:02 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id DBB814066D01; Tue, 1 Dec 2015 18:59:58 +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; Tue, 1 Dec 2015 18:59:58 +0800 From: Dongsheng Yang To: , Subject: [PATCH v1 5/7] mtd: mtd_raid: introduce raid0 implementation Date: Tue, 1 Dec 2015 18:52:35 +0800 Message-ID: <1448967157-17423-6-git-send-email-yangds.fnst@cn.fujitsu.com> X-Mailer: git-send-email 1.8.4.2 In-Reply-To: <1448967157-17423-1-git-send-email-yangds.fnst@cn.fujitsu.com> References: <1448967157-17423-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: DBB814066D01.A52D2 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-20151201_030112_587526_57EB17C8 X-CRM114-Status: GOOD ( 14.33 ) 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 , linux-mtd@lists.infradead.org Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org This is implementation of raid0, the main work of it is mapping logical address to physical address. Signed-off-by: Dongsheng Yang --- drivers/mtd/mtd_raid/raid0.c | 136 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 drivers/mtd/mtd_raid/raid0.c diff --git a/drivers/mtd/mtd_raid/raid0.c b/drivers/mtd/mtd_raid/raid0.c new file mode 100644 index 0000000..e95a6a9 --- /dev/null +++ b/drivers/mtd/mtd_raid/raid0.c @@ -0,0 +1,136 @@ +/* + * 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 raid0. + * RAID0: + * + * Flash A: + * ------------------------------ + * | A1 | A2 | ... | An | + * ------------------------------ + * Flash B: + * ------------------------------ + * | B1 | B2 | ... | Bn | + * ------------------------------ + * Flash C: + * ------------------------------ + * | C1 | C2 | ... | Cn | + * ------------------------------ + * + * RAID_SINGLE: + * ----------------------------------------------------------------------- + * | A1 | B1 | C1 | A2 | B2 | C2 | ... | An | Bn | Cn | + * ----------------------------------------------------------------------- + * + * Detail to see: + * https://en.wikipedia.org/wiki/Standard_RAID_levels + */ + +#include +#include + +#include "mtd_raid.h" + +static int raid0_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) +{ + loff_t stripe_size, stripe_offs, stripe_num, substripe_offs, substripe_num; + + stripe_size = raid->substripe_size * raid->npebs_per_leb; + stripe_offs = do_div(from, stripe_size); + stripe_num = from; + substripe_offs = do_div(stripe_offs, raid->substripe_size); + substripe_num = stripe_offs; + + *devid = substripe_num; + *subdev_off = stripe_num * raid->substripe_size + substripe_offs; + *size = len; + if (*size > raid->substripe_size - substripe_offs) + *size = raid->substripe_size - substripe_offs; + + return 0; +} + +struct mtd_raid *mtd_raid0_create(int *mtd_nums, int dev_count, size_t substripe_size) +{ + struct mtd_raid0 *raid0 = NULL; + struct mtd_raid *raid = NULL; + + raid0 = kzalloc(sizeof(struct mtd_raid0) + sizeof(struct mtd_raid_dev) * dev_count, GFP_KERNEL); + if (!raid0) + goto out; + + raid = &raid0->raid; + raid->raid_level = MTD_RAID_LEVEL_RAID0; + raid->ops = &mtd_raid0_ops; + raid->ncopies = 1; + raid->npebs_per_leb = dev_count; + + return &raid0->raid; +out: + return NULL; +} + +static int raid0_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 *subdev0 = raid->devs[0].mtd; + struct mtd_info *subdev = NULL; + + raid_id = mtd_raid_list_register(MTD_RAID_LEVEL_RAID0, raid); + sprintf(raid->name, "mtd0-%d", raid_id); + mtd->name = raid->name; + + for (i = 0; i < dev_count; i++) { + subdev = raid->devs[i].mtd; + if (subdev0->size != subdev->size) { + pr_err("Incompatible size on \"%s\"", + subdev->name); + ret = -EINVAL; + goto out; + } + + mtd->size += subdev->size; + mtd->erasesize += subdev->erasesize; + } +out: + return ret; +} + + +void raid0_destroy(struct mtd_raid *mtd_raid) +{ + struct mtd_raid0 *raid0 = MTD_RAID_RAID0(mtd_raid); + + mtd_raid_list_unregister(&raid0->raid); + kfree(raid0); +} + +const struct mtd_raid_operations mtd_raid0_ops = { + .init = raid0_init, + .destroy = raid0_destroy, + .logical_to_physical = raid0_logical_to_physical, +};