[PATCH v2 5/7] mtd: mtd_raid: introduce raid0 implementation

Dongsheng Yang yangds.fnst at cn.fujitsu.com
Sat Dec 12 00:41:05 PST 2015


This is implementation of raid0, the main work of it
is mapping logical address to physical address.

Signed-off-by: Dongsheng Yang <yangds.fnst at cn.fujitsu.com>
---
 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..d72a6b7
--- /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 <yangds.fnst at cn.fujitsu.com>
+ */
+
+/**
+ * This file implement raid0.
+ * RAID0:
+ *
+ * Flash A:
+ * 	------------------------------
+ * 	|  A1   |  A2   | ... |  An  |
+ * 	------------------------------
+ * Flash B:
+ * 	------------------------------
+ * 	|  B1   |  B2   | ... |  Bn  |
+ * 	------------------------------
+ * Flash C:
+ * 	------------------------------
+ * 	|  C1   |  C2   | ... |  Cn  |
+ * 	------------------------------
+ *
+ * RAID0:
+ * 	-----------------------------------------------------------------------
+ * 	|  A1   |  B1  |  C1  |  A2  |  B2  |  C2  | ... |  An  |  Bn  |  Cn  |
+ * 	-----------------------------------------------------------------------
+ *
+ * Detail to see:
+ * https://en.wikipedia.org/wiki/Standard_RAID_levels
+ */
+
+#include <linux/slab.h>
+#include <linux/kthread.h>
+
+#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 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,
+};
-- 
1.8.4.2






More information about the linux-mtd mailing list