From patchwork Tue Dec 1 10:52:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongsheng Yang X-Patchwork-Id: 550780 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 B41991401DA for ; Tue, 1 Dec 2015 22:03:14 +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 1a3ig8-0001lC-Tn; Tue, 01 Dec 2015 11:01:00 +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 1a3ig2-0001cs-T4 for linux-mtd@lists.infradead.org; Tue, 01 Dec 2015 11:00:58 +0000 X-IronPort-AV: E=Sophos;i="5.20,346,1444665600"; d="scan'208";a="1035776" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 01 Dec 2015 19:00:00 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id 4EA7D40427D0; 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:57 +0800 From: Dongsheng Yang To: , Subject: [PATCH v1 4/7] mtd: mtd_raid: introduce raid single implementation Date: Tue, 1 Dec 2015 18:52:34 +0800 Message-ID: <1448967157-17423-5-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: 4EA7D40427D0.A40F4 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_030057_115098_9062FA62 X-CRM114-Status: GOOD ( 15.37 ) 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 impletion of raid-single, raid-single works similar with mtd_concat. Signed-off-by: Dongsheng Yang --- drivers/mtd/mtd_raid/raid_single.c | 156 +++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 drivers/mtd/mtd_raid/raid_single.c diff --git a/drivers/mtd/mtd_raid/raid_single.c b/drivers/mtd/mtd_raid/raid_single.c new file mode 100644 index 0000000..e1421d0 --- /dev/null +++ b/drivers/mtd/mtd_raid/raid_single.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 single raild level. + * + * RAID_SINGLE: + * + * Flash A: + * ------------------------------ + * | A1 | A2 | ... | An | + * ------------------------------ + * Flash B: + * ------------------------------ + * | B1 | B2 | ... | Bn | + * ------------------------------ + * Flash C: + * ------------------------------ + * | C1 | C2 | ... | Cn | + * ------------------------------ + * + * RAID_SINGLE: + * --------------------------------------------------------------------- + * | A1 | A2 | ... | An | B1 | ... | Bn | C1 | ... | Cn | + * --------------------------------------------------------------------- + * + * It works similarly with concat. + */ +#include +#include + +#include "mtd_raid.h" + +/** + * + */ +static int raid_single_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) +{ + struct mtd_info *subdev = NULL; + int i = 0; + + *subdev_off = from; + for (i = 0; i < raid->dev_count; i++) { + subdev = raid->devs[i].mtd; + if (from >= subdev->size) { + from -= subdev->size; + *subdev_off = 0; + *size = 0; + continue; + } + + *subdev_off = from; + if (from + len > subdev->size) + *size = subdev->size - *subdev_off; + else + *size = len; + + *devid = i; + break; + } + + if (i == raid->dev_count) + return -EINVAL; + + return 0; +} + +struct mtd_raid *mtd_raid_single_create(int *mtd_nums, int dev_count, size_t substripe_size) +{ + struct mtd_raid_single *raid_single = NULL; + struct mtd_raid *raid = NULL; + + raid_single = kzalloc(sizeof(struct mtd_raid_single) + sizeof(struct mtd_raid_dev) * dev_count, GFP_KERNEL); + if (!raid_single) + goto out; + + raid = &raid_single->raid; + raid->raid_level = MTD_RAID_LEVEL_SINGLE; + raid->ops = &mtd_raid_single_ops; + raid->ncopies = 1; + raid->npebs_per_leb = 1; + + return &raid_single->raid; +out: + return NULL; +} + +static int raid_single_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_SINGLE, raid); + sprintf(raid->name, "mtdsingle-%d", raid_id); + mtd->name = raid->name; + + /* + * Same erasesize with subdevs + **/ + mtd->erasesize = subdev->erasesize; + for (i = 0; i < dev_count; i++) { + subdev = raid->devs[i].mtd; + if (mtd->erasesize != subdev->erasesize) { + pr_err("Incompatible erasesize on \"%s\"", + subdev->name); + ret = -EINVAL; + goto err; + } + /* + * mtd->size is the sum of all subdevs + **/ + mtd->size += subdev->size; + } + return ret; +err: + mtd_raid_list_unregister(raid); + return ret; +} + + +static void raid_single_destroy(struct mtd_raid *mtd_raid) +{ + struct mtd_raid_single *raid_single = MTD_RAID_SINGLE(mtd_raid); + + mtd_raid_list_unregister(&raid_single->raid); + kfree(raid_single); +} + +const struct mtd_raid_operations mtd_raid_single_ops = { + .init = raid_single_init, + .destroy = raid_single_destroy, + .logical_to_physical = raid_single_logical_to_physical, +};