From: Konstantin Baydarov <kbaidarov@dev.rtsoft.ru>
To: Konstantin Baydarov <kbaidarov@dev.rtsoft.ru>
Cc: linux-mtd@lists.infradead.org, Vitaly Wool <vwool@ru.mvista.com>
Subject: Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD
Date: Sat, 2 Dec 2006 19:41:03 +0300 [thread overview]
Message-ID: <20061202194103.28f04a93@localhost.localdomain> (raw)
In-Reply-To: <20061122195633.0719c264@localhost.localdomain>
On Wed, 22 Nov 2006 19:56:33 +0300
Konstantin Baydarov <kbaidarov@dev.rtsoft.ru> wrote:
>
> Corrected typo, renamed driver, got rid from redundant dependency.
> Also I've tested mtdblock_ro_bbfree as module - ok.
Renamed driver to 'romblock'. Every entry of 'mtdblock' was replaced.
Debug level in DEBUG macros was replaced by corresponding macros.
drivers/mtd/Kconfig | 7 ++
drivers/mtd/Makefile | 1
drivers/mtd/romblock.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 173 insertions(+)
Index: mtd-2.6/drivers/mtd/romblock.c
===================================================================
--- /dev/null
+++ mtd-2.6/drivers/mtd/romblock.c
@@ -0,0 +1,165 @@
+/*
+ * Readonly Block Device Layer Over MTD
+ *
+ * (C) 2006 Baydarov Konstantin <kbaidarov@dev.rtsoft.ru>
+ * Pantelis Antoniou <panto@intracom.gr>
+ * David Woodhouse <dwmw2@infradead.org>
+ *
+ * It allows to use any filesystem on this device in
+ * RO mode and thus gain faster mount times and better
+ * throughput rates.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/blktrans.h>
+
+struct romblock_map {
+ struct mtd_blktrans_dev dev;
+ /* block map for RO */
+ int32_t *block_map;
+ int32_t block_top;
+ int32_t block_scantop;
+};
+
+static loff_t map_over_bad_blocks(struct mtd_blktrans_dev* dev, loff_t from)
+{
+ int i, block;
+ struct mtd_info *mtd = dev->mtd;
+ struct romblock_map* dev_cont = container_of(dev, struct romblock_map, dev);
+ int32_t *block_map = dev_cont->block_map;
+ int32_t block_top = dev_cont->block_top;
+ int32_t block_scantop = dev_cont->block_scantop;
+
+ /* if no bad block checking is possible bail out */
+ if (mtd->block_isbad == NULL)
+ return from;
+
+ /* first time in */
+ if (block_map == NULL) {
+ block_top = mtd->size / mtd->erasesize;
+ block_map = kmalloc(sizeof(*block_map) * block_top, GFP_KERNEL);
+ if (block_map == NULL) {
+ printk (KERN_ERR "map_over_bad_blocks(): unable to allocate block map\n");
+ return -ENOMEM;
+ }
+ for (i = 0; i < block_top; i++)
+ block_map[i] = -1;
+
+ for (i = 0; i < block_top; i++)
+ if ((*mtd->block_isbad)(mtd, i * mtd->erasesize) == 0)
+ break;
+
+ if (i >= block_top) {
+ printk (KERN_WARNING "map_over_bad_blocks(): all blocks bad!\n");
+ return -EIO;
+ }
+ block_scantop = 0;
+ block_map[0] = i;
+
+ DEBUG(MTD_DEBUG_LEVEL0, "mtd: map %d -> %d\n", block_scantop, block_map[block_scantop]);
+ }
+
+ block = ((int)from / mtd->erasesize);
+ if (block >= block_top)
+ return (loff_t)-1;
+
+ /* scan for bad block up to where we want */
+ while (block >= block_scantop) {
+ /* find a non bad block */
+ for (i = block_map[block_scantop] + 1; i < block_top; i++)
+ if ((*mtd->block_isbad)(mtd, i * mtd->erasesize) == 0)
+ break;
+
+ /* exhausted ? */
+ if (i >= block_top) {
+ printk (KERN_WARNING "map_over_bad_blocks(): no more good blocks!\n");
+ return (loff_t)-1;
+ }
+
+ block_map[++block_scantop] = i;
+ DEBUG(MTD_DEBUG_LEVEL0, "mtd: map %d -> %d\n", block_scantop, block_map[block_scantop]);
+ }
+
+ block = block_map[(int)from / mtd->erasesize];
+ from = (block * mtd->erasesize) | ((int)from & (mtd->erasesize - 1));
+ return from;
+}
+
+static int romblock_readsect(struct mtd_blktrans_dev *dev,
+ unsigned long block, char *buf)
+{
+ size_t retlen;
+ unsigned long from;
+
+ from = map_over_bad_blocks(dev, block<<9);
+
+ if (dev->mtd->read(dev->mtd, from, 512, &retlen, buf))
+ return 1;
+ return 0;
+}
+
+static int romblock_writesect(struct mtd_blktrans_dev *dev,
+ unsigned long block, char *buf)
+{
+ size_t retlen;
+
+ if (dev->mtd->write(dev->mtd, (block * 512), 512, &retlen, buf))
+ return 1;
+ return 0;
+}
+
+static void romblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
+{
+ struct romblock_map *dev_cont = kmalloc(sizeof(*dev_cont), GFP_KERNEL);
+
+ if (!dev_cont)
+ return;
+
+ memset(dev_cont, 0, sizeof(*dev_cont));
+
+ dev_cont->dev.mtd = mtd;
+ dev_cont->dev.devnum = mtd->index;
+ dev_cont->dev.blksize = 512;
+ dev_cont->dev.size = mtd->size >> 9;
+ dev_cont->dev.tr = tr;
+ dev_cont->dev.readonly = 1;
+
+ add_mtd_blktrans_dev(&(dev_cont->dev));
+}
+
+static void romblock_remove_dev(struct mtd_blktrans_dev *dev)
+{
+ del_mtd_blktrans_dev(dev);
+ kfree(dev);
+}
+
+static struct mtd_blktrans_ops romblock_tr = {
+ .name = "romblock",
+ .major = 258,
+ .part_bits = 0,
+ .readsect = romblock_readsect,
+ .writesect = romblock_writesect,
+ .add_mtd = romblock_add_mtd,
+ .remove_dev = romblock_remove_dev,
+ .owner = THIS_MODULE,
+};
+
+static int __init romblock_init(void)
+{
+ return register_mtd_blktrans(&romblock_tr);
+}
+
+static void __exit romblock_exit(void)
+{
+ deregister_mtd_blktrans(&romblock_tr);
+}
+
+module_init(romblock_init);
+module_exit(romblock_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Baydarov Konstantin <kbaidarov@dev.rtsoft.ru>");
+MODULE_DESCRIPTION("Readonly Block Device Layer Over MTD");
Index: mtd-2.6/drivers/mtd/Makefile
===================================================================
--- mtd-2.6.orig/drivers/mtd/Makefile
+++ mtd-2.6/drivers/mtd/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_CHAR) += mtdchar.o
obj-$(CONFIG_MTD_BLOCK) += mtdblock.o mtd_blkdevs.o
obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o mtd_blkdevs.o
+obj-$(CONFIG_MTD_BLOCK_ROMBLOCK) += romblock.o mtd_blkdevs.o
obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o
obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o
obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o
Index: mtd-2.6/drivers/mtd/Kconfig
===================================================================
--- mtd-2.6.orig/drivers/mtd/Kconfig
+++ mtd-2.6/drivers/mtd/Kconfig
@@ -197,6 +197,13 @@ config MTD_BLOCK_RO
You do not need this option for use with the DiskOnChip devices. For
those, enable NFTL support (CONFIG_NFTL) instead.
+config MTD_BLOCK_ROMBLOCK
+ tristate "Readonly Block Device Layer Over MTD"
+ depends on MTD_BLOCK!=y && MTD
+ help
+ Same as readonly block driver, but this allow you to mount read-only file
+ systems from an MTD device, containing bad blocks.
+
config FTL
tristate "FTL (Flash Translation Layer) support"
depends on MTD && BLOCK
next prev parent reply other threads:[~2006-12-02 16:36 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-11-17 15:40 [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD kbaidarov
2006-11-18 13:15 ` Artem Bityutskiy
2006-11-18 13:33 ` Josh Boyer
2006-11-18 13:35 ` Artem Bityutskiy
2006-11-18 13:40 ` Artem Bityutskiy
2006-11-20 12:15 ` Vitaly Wool
2006-11-20 12:46 ` Artem Bityutskiy
2006-11-20 13:06 ` Vitaly Wool
2006-11-20 13:39 ` Artem Bityutskiy
2006-11-20 13:20 ` Konstantin Baydarov
2006-11-20 12:11 ` Vitaly Wool
2006-11-20 12:05 ` Vitaly Wool
2006-11-20 14:52 ` Josh Boyer
2006-11-21 10:30 ` Vitaly Wool
2006-11-22 16:56 ` Konstantin Baydarov
2006-12-02 16:41 ` Konstantin Baydarov [this message]
2007-09-27 15:05 ` Gregory CLEMENT
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061202194103.28f04a93@localhost.localdomain \
--to=kbaidarov@dev.rtsoft.ru \
--cc=linux-mtd@lists.infradead.org \
--cc=vwool@ru.mvista.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.