* [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD
@ 2006-11-17 15:40 kbaidarov
2006-11-18 13:15 ` Artem Bityutskiy
` (2 more replies)
0 siblings, 3 replies; 17+ messages in thread
From: kbaidarov @ 2006-11-17 15:40 UTC (permalink / raw)
To: linux-mtd
Description:
The following patch adds readonly block device layer over mtd
that allows to use any filesystem on this device in RO mode and
thus gain faster mount times and better throughput rates.
How it works:
Blocks translation routine was added to read sector function. Assuming
that bad block won't appear during MTD reading and BBT is correct, bad
block is skipped and requested block is lazily mapped to good one.
Block driver based on the mtd readonly device driver mtdblock_ro.c and
translation routine was taken from the patch of Pantelis Antoniou
(which can be found at
http://lists.infradead.org/pipermail/linux-mtd/2004-May/009672.html).
Large major 258 has already been assigned by LANANA.
Signed-off-by: Konstantin Baydarov <kbaidarov@dev.rtsoft.ru>
drivers/mtd/Kconfig | 7 +
drivers/mtd/Makefile | 1
drivers/mtd/mtdblock_ro_bbfree.c | 165 +++++++++++++++++++++++++++++++++++++++
3 files changed, 173 insertions(+)
Index: mips-kernel-2.6/drivers/mtd/mtdblock_ro_bbfree.c
===================================================================
--- /dev/null
+++ mips-kernel-2.6/drivers/mtd/mtdblock_ro_bbfree.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 mtd_block_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 mtd_block_map* dev_cont = container_of(dev, struct mtd_block_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_WARNING "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(0, "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;
+
+ /* exchausted ? */
+ 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(0, "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 mtdblock_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 mtdblock_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 mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
+{
+ struct mtd_block_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 mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
+{
+ del_mtd_blktrans_dev(dev);
+ kfree(dev);
+}
+
+static struct mtd_blktrans_ops mtdblock_tr = {
+ .name = "mtdblock",
+ .major = 258,
+ .part_bits = 0,
+ .readsect = mtdblock_readsect,
+ .writesect = mtdblock_writesect,
+ .add_mtd = mtdblock_add_mtd,
+ .remove_dev = mtdblock_remove_dev,
+ .owner = THIS_MODULE,
+};
+
+static int __init mtdblock_init(void)
+{
+ return register_mtd_blktrans(&mtdblock_tr);
+}
+
+static void __exit mtdblock_exit(void)
+{
+ deregister_mtd_blktrans(&mtdblock_tr);
+}
+
+module_init(mtdblock_init);
+module_exit(mtdblock_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Baydarov Konstantin <kbaidarov@dev.rtsoft.ru>");
+MODULE_DESCRIPTION("Readonly Block Device Layer Over MTD");
Index: mips-kernel-2.6/drivers/mtd/Makefile
===================================================================
--- mips-kernel-2.6.orig/drivers/mtd/Makefile
+++ mips-kernel-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_RO_BBFREE) += mtdblock_ro_bbfree.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: mips-kernel-2.6/drivers/mtd/Kconfig
===================================================================
--- mips-kernel-2.6.orig/drivers/mtd/Kconfig
+++ mips-kernel-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_RO_BBFREE
+ tristate "Readonly bad block free block device access to MTD devices"
+ depends on MTD_BLOCK!=y && MTD && MTD_BLOCK_RO!=y
+ 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
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 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-20 12:11 ` Vitaly Wool 2006-11-20 12:05 ` Vitaly Wool 2006-11-20 14:52 ` Josh Boyer 2 siblings, 2 replies; 17+ messages in thread From: Artem Bityutskiy @ 2006-11-18 13:15 UTC (permalink / raw) To: kbaidarov; +Cc: linux-mtd Hello Konstantin, On Fri, 2006-11-17 at 18:40 +0300, kbaidarov wrote: > Description: > The following patch adds readonly block device layer over mtd > that allows to use any filesystem on this device in RO mode and > thus gain faster mount times and better throughput rates. This is very ambition claim. In comparison with what? > How it works: > Blocks translation routine was added to read sector function. Assuming > that bad block won't appear during MTD reading and BBT is correct, bad > block is skipped and requested block is lazily mapped to good one. > Block driver based on the mtd readonly device driver mtdblock_ro.c and > translation routine was taken from the patch of Pantelis Antoniou > (which can be found at > http://lists.infradead.org/pipermail/linux-mtd/2004-May/009672.html). > So basically this is bad eraseblock-aware mtdblock_ro? But why you created a new driver and with so weird name :-) ? Why didn't you just changed mtdblock_ro? IOW, why you didn't adapt Pantelis' patch instead and re-send it? (I have no idea why this patch isn't im MTD still, -- Best regards, Artem Bityutskiy (Битюцкий Артём) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 2006-11-18 13:15 ` Artem Bityutskiy @ 2006-11-18 13:33 ` Josh Boyer 2006-11-18 13:35 ` Artem Bityutskiy 2006-11-20 12:11 ` Vitaly Wool 1 sibling, 1 reply; 17+ messages in thread From: Josh Boyer @ 2006-11-18 13:33 UTC (permalink / raw) To: dedekind; +Cc: linux-mtd, kbaidarov On Sat, 2006-11-18 at 15:15 +0200, Artem Bityutskiy wrote: > Hello Konstantin, > > On Fri, 2006-11-17 at 18:40 +0300, kbaidarov wrote: > > Description: > > The following patch adds readonly block device layer over mtd > > that allows to use any filesystem on this device in RO mode and > > thus gain faster mount times and better throughput rates. > > This is very ambition claim. In comparison with what? > > > How it works: > > Blocks translation routine was added to read sector function. Assuming > > that bad block won't appear during MTD reading and BBT is correct, bad > > block is skipped and requested block is lazily mapped to good one. > > Block driver based on the mtd readonly device driver mtdblock_ro.c and > > translation routine was taken from the patch of Pantelis Antoniou > > (which can be found at > > http://lists.infradead.org/pipermail/linux-mtd/2004-May/009672.html). > > > > So basically this is bad eraseblock-aware mtdblock_ro? But why you > created a new driver and with so weird name :-) ? Why didn't you just > changed mtdblock_ro? IOW, why you didn't adapt Pantelis' patch instead > and re-send it? (I have no idea why this patch isn't im MTD still, Because we've consistently told people not to do that. josh ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 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 0 siblings, 2 replies; 17+ messages in thread From: Artem Bityutskiy @ 2006-11-18 13:35 UTC (permalink / raw) To: Josh Boyer; +Cc: linux-mtd, kbaidarov On Sat, 2006-11-18 at 07:33 -0600, Josh Boyer wrote: > Because we've consistently told people not to do that. OK, but why ? -- Best regards, Artem Bityutskiy (Битюцкий Артём) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 2006-11-18 13:35 ` Artem Bityutskiy @ 2006-11-18 13:40 ` Artem Bityutskiy 2006-11-20 12:15 ` Vitaly Wool 1 sibling, 0 replies; 17+ messages in thread From: Artem Bityutskiy @ 2006-11-18 13:40 UTC (permalink / raw) To: Josh Boyer; +Cc: linux-mtd, kbaidarov On Sat, 2006-11-18 at 15:35 +0200, Artem Bityutskiy wrote: > On Sat, 2006-11-18 at 07:33 -0600, Josh Boyer wrote: > > Because we've consistently told people not to do that. > > OK, but why ? > I didn't review this, but I don't see anything bad to do like this http://lists.infradead.org/pipermail/linux-mtd/2004-May/009683.html for mtdblock_ro. What are the objections? -- Best regards, Artem Bityutskiy (Битюцкий Артём) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 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 1 sibling, 1 reply; 17+ messages in thread From: Vitaly Wool @ 2006-11-20 12:15 UTC (permalink / raw) To: dedekind; +Cc: linux-mtd, kbaidarov Artem Bityutskiy wrote: > On Sat, 2006-11-18 at 07:33 -0600, Josh Boyer wrote: > >> Because we've consistently told people not to do that. >> > > OK, but why ? > > B/c it introduces new fields in generic mtd structures which are already overcomplicated, and modifies a lot of generic code. I'd expect that with this patch applied stuff like mtdcore.c and mtdpart.c becomes exposed to possible licensing issues which is definitely not what we aim ;-) Vitaly ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 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:20 ` Konstantin Baydarov 0 siblings, 2 replies; 17+ messages in thread From: Artem Bityutskiy @ 2006-11-20 12:46 UTC (permalink / raw) To: Vitaly Wool; +Cc: linux-mtd, kbaidarov On Mon, 2006-11-20 at 15:15 +0300, Vitaly Wool wrote: > B/c it introduces new fields in generic mtd structures which are already > overcomplicated, and modifies a lot of generic code. I'd expect that > with this patch applied stuff like mtdcore.c and mtdpart.c becomes > exposed to possible licensing issues which is definitely not what we aim ;-) I am talking about something like this: http://lists.infradead.org/pipermail/linux-mtd/2004-May/009683.html I do not see it introducing any new field. -- Best regards, Artem Bityutskiy (Битюцкий Артём) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 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 1 sibling, 1 reply; 17+ messages in thread From: Vitaly Wool @ 2006-11-20 13:06 UTC (permalink / raw) To: dedekind; +Cc: linux-mtd, kbaidarov Artem Bityutskiy wrote: > I am talking about something like this: > > http://lists.infradead.org/pipermail/linux-mtd/2004-May/009683.html > This one unconditionally changes mtdblock, doesn't it? ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 2006-11-20 13:06 ` Vitaly Wool @ 2006-11-20 13:39 ` Artem Bityutskiy 0 siblings, 0 replies; 17+ messages in thread From: Artem Bityutskiy @ 2006-11-20 13:39 UTC (permalink / raw) To: Vitaly Wool; +Cc: linux-mtd, kbaidarov On Mon, 2006-11-20 at 16:06 +0300, Vitaly Wool wrote: > Artem Bityutskiy wrote: > > I am talking about something like this: > > > > http://lists.infradead.org/pipermail/linux-mtd/2004-May/009683.html > > > This one unconditionally changes mtdblock, doesn't it? Yes. Basically speaking, mtdblock was designed for NOR flashes and there were no bad eraseblocks at all. Now you want to utilize it on NANDs. So you add BB-awareness functionality. And I still think you should changd mtdblock_ro instead of adding new driver. Why? Because if you change mtdblock_ro: 1. you do not change semantics at all. in case of old BB-less flashes all stays the same old way. So I do not understand why you need a new device number. 2. You make mtdblock_ro workable on NAND. You extend it. You have right to slightly change the semantics. 1:1 mapping makes no sense in this case, so it is logical to skip bad blocks. Instead you add a new driver. Strange. -- Best regards, Artem Bityutskiy (Битюцкий Артём) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 2006-11-20 12:46 ` Artem Bityutskiy 2006-11-20 13:06 ` Vitaly Wool @ 2006-11-20 13:20 ` Konstantin Baydarov 1 sibling, 0 replies; 17+ messages in thread From: Konstantin Baydarov @ 2006-11-20 13:20 UTC (permalink / raw) To: dedekind; +Cc: Vitaly Wool, linux-mtd Artem Bityutskiy wrote: > On Mon, 2006-11-20 at 15:15 +0300, Vitaly Wool wrote: > >>B/c it introduces new fields in generic mtd structures which are already >>overcomplicated, and modifies a lot of generic code. I'd expect that >>with this patch applied stuff like mtdcore.c and mtdpart.c becomes >>exposed to possible licensing issues which is definitely not what we aim ;-) > > > I am talking about something like this: > > http://lists.infradead.org/pipermail/linux-mtd/2004-May/009683.html > > I do not see it introducing any new field. > I realized it exactly the same way on top of readoly block device. Patch, you talking about, definitely needs #ifdef-s and it waste kernel RAM statically allocating block_map, block_top, block_scantop MAX_MTD_DEVICES times :-). ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 2006-11-18 13:15 ` Artem Bityutskiy 2006-11-18 13:33 ` Josh Boyer @ 2006-11-20 12:11 ` Vitaly Wool 1 sibling, 0 replies; 17+ messages in thread From: Vitaly Wool @ 2006-11-20 12:11 UTC (permalink / raw) To: dedekind; +Cc: linux-mtd, kbaidarov Hi Artem, Artem Bityutskiy wrote: > Hello Konstantin, > > On Fri, 2006-11-17 at 18:40 +0300, kbaidarov wrote: > >> Description: >> The following patch adds readonly block device layer over mtd >> that allows to use any filesystem on this device in RO mode and >> thus gain faster mount times and better throughput rates. >> > > This is very ambition claim. In comparison with what? > With JFFS2, for instance. I hope you won't argue than squashfs is faster to mount than JFFS2. :-) Please keep in mind that this is for read-only access. > So basically this is bad eraseblock-aware mtdblock_ro? But why you > created a new driver and with so weird name :-) ? Why didn't you just > changed mtdblock_ro? IOW, why you didn't adapt Pantelis' patch instead > and re-send it? (I have no idea why this patch isn't im MTD still, > > Erm, these are several questions in one. First, this "shim" was arranged as a new driver per dwmw2's request. It was our first idea to modify mtdblock_ro, but it didn't work for David. Next, I pretty much don't understand your phrase about the "weird name", though I might be missing something. And the final thing is this approach is a derivative of Pantelis's patch. There were several "points of evolution" within. Please note that unlikely to Pantelis's patch, we now don't introduce *any* new fields or ifdef's in the generic code, there's no modifications in the existing code as well. It became a separate solution 5 screens worth :) It's a very low price for being able to use cramfs/squashfs/fat in read-only on NAND flash for embedded systems. Vitaly ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 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-20 12:05 ` Vitaly Wool 2006-11-20 14:52 ` Josh Boyer 2 siblings, 0 replies; 17+ messages in thread From: Vitaly Wool @ 2006-11-20 12:05 UTC (permalink / raw) To: kbaidarov; +Cc: linux-mtd kbaidarov wrote: > Description: > The following patch adds readonly block device layer over mtd > that allows to use any filesystem on this device in RO mode and > thus gain faster mount times and better throughput rates. > > How it works: > Blocks translation routine was added to read sector function. Assuming > that bad block won't appear during MTD reading and BBT is correct, bad > block is skipped and requested block is lazily mapped to good one. > Block driver based on the mtd readonly device driver mtdblock_ro.c and > translation routine was taken from the patch of Pantelis Antoniou > (which can be found at > http://lists.infradead.org/pipermail/linux-mtd/2004-May/009672.html). > > Large major 258 has already been assigned by LANANA. > > Signed-off-by: Konstantin Baydarov <kbaidarov@dev.rtsoft.ru> > Acked-by: Vitaly Wool <vwool@ru.mvista.com> ;-) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 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-20 12:05 ` Vitaly Wool @ 2006-11-20 14:52 ` Josh Boyer 2006-11-21 10:30 ` Vitaly Wool 2 siblings, 1 reply; 17+ messages in thread From: Josh Boyer @ 2006-11-20 14:52 UTC (permalink / raw) To: kbaidarov; +Cc: linux-mtd On Fri, 2006-11-17 at 18:40 +0300, kbaidarov wrote: > + /* 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; > + > + /* exchausted ? */ exhausted > +static struct mtd_blktrans_ops mtdblock_tr = { > + .name = "mtdblock", > + .major = 258, > + .part_bits = 0, > + .readsect = mtdblock_readsect, > + .writesect = mtdblock_writesect, > + .add_mtd = mtdblock_add_mtd, > + .remove_dev = mtdblock_remove_dev, > + .owner = THIS_MODULE, > +}; You went to the trouble of getting a new major number assigned... why not call it something other than mtdblock? > Index: mips-kernel-2.6/drivers/mtd/Makefile > =================================================================== > --- mips-kernel-2.6.orig/drivers/mtd/Makefile > +++ mips-kernel-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_RO_BBFREE) += mtdblock_ro_bbfree.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 All these mtd_blkdevs.o are starting to get ugly. Why don't we introduce a CONFIG_MTDBLKDEVS that can be selected by the other Kconfig options. > Index: mips-kernel-2.6/drivers/mtd/Kconfig > =================================================================== > --- mips-kernel-2.6.orig/drivers/mtd/Kconfig > +++ mips-kernel-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_RO_BBFREE > + tristate "Readonly bad block free block device access to MTD devices" > + depends on MTD_BLOCK!=y && MTD && MTD_BLOCK_RO!=y > + help > + Same as readonly block driver, but this allow you to mount read-only file > + systems from an MTD device, containing bad blocks. > + This part seems hacky to me... why can't use use mtdblock or mtdblock_ro when this is enabled? And what happens in the module case? josh ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 2006-11-20 14:52 ` Josh Boyer @ 2006-11-21 10:30 ` Vitaly Wool 2006-11-22 16:56 ` Konstantin Baydarov 0 siblings, 1 reply; 17+ messages in thread From: Vitaly Wool @ 2006-11-21 10:30 UTC (permalink / raw) To: Josh Boyer; +Cc: linux-mtd, kbaidarov Josh Boyer wrote: <snip> >> +static struct mtd_blktrans_ops mtdblock_tr = { >> + .name = "mtdblock", >> + .major = 258, >> + .part_bits = 0, >> + .readsect = mtdblock_readsect, >> + .writesect = mtdblock_writesect, >> + .add_mtd = mtdblock_add_mtd, >> + .remove_dev = mtdblock_remove_dev, >> + .owner = THIS_MODULE, >> +}; >> > > You went to the trouble of getting a new major number assigned... why > not call it something other than mtdblock? > Agree. > >> Index: mips-kernel-2.6/drivers/mtd/Kconfig >> =================================================================== >> --- mips-kernel-2.6.orig/drivers/mtd/Kconfig >> +++ mips-kernel-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_RO_BBFREE >> + tristate "Readonly bad block free block device access to MTD devices" >> + depends on MTD_BLOCK!=y && MTD && MTD_BLOCK_RO!=y >> + help >> + Same as readonly block driver, but this allow you to mount read-only file >> + systems from an MTD device, containing bad blocks. >> + >> > > This part seems hacky to me... why can't use use mtdblock or > mtdblock_ro when this is enabled? And what happens in the module case? > I guess this line is borrowed from MTD_BLOCK_RO: config MTD_BLOCK_RO tristate "Readonly block device access to MTD devices" depends on MTD_BLOCK!=y && MTD && BLOCK I think though that these limitations are redundant at least for MTD_BLOCK_RO_BBFREE b/c there might be the cases where there're both NAND and NOR chips in the system so MTD_BLOCK_RO and MTD_BLOCK_RO_BBFREE might be needed to be present in the system at the same time. Vitaly ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 2006-11-21 10:30 ` Vitaly Wool @ 2006-11-22 16:56 ` Konstantin Baydarov 2006-12-02 16:41 ` Konstantin Baydarov 0 siblings, 1 reply; 17+ messages in thread From: Konstantin Baydarov @ 2006-11-22 16:56 UTC (permalink / raw) To: Vitaly Wool; +Cc: linux-mtd [-- Attachment #1: Type: text/plain, Size: 3379 bytes --] On Tue, 21 Nov 2006 13:30:15 +0300 Vitaly Wool <vwool@ru.mvista.com> wrote: > Josh Boyer wrote: > > <snip> > >> +static struct mtd_blktrans_ops mtdblock_tr = { > >> + .name = "mtdblock", > >> + .major = 258, > >> + .part_bits = 0, > >> + .readsect = mtdblock_readsect, > >> + .writesect = mtdblock_writesect, > >> + .add_mtd = mtdblock_add_mtd, > >> + .remove_dev = mtdblock_remove_dev, > >> + .owner = THIS_MODULE, > >> +}; > >> > > > > You went to the trouble of getting a new major number assigned... > > why not call it something other than mtdblock? > > > Agree. > > > >> Index: mips-kernel-2.6/drivers/mtd/Kconfig > >> =================================================================== > >> --- mips-kernel-2.6.orig/drivers/mtd/Kconfig > >> +++ mips-kernel-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_RO_BBFREE > >> + tristate "Readonly bad block free block device access to > >> MTD devices" > >> + depends on MTD_BLOCK!=y && MTD && MTD_BLOCK_RO!=y > >> + help > >> + Same as readonly block driver, but this allow you to > >> mount read-only file > >> + systems from an MTD device, containing bad blocks. > >> + > >> > > > > This part seems hacky to me... why can't use use mtdblock or > > mtdblock_ro when this is enabled? And what happens in the module > > case? > I guess this line is borrowed from MTD_BLOCK_RO: > > config MTD_BLOCK_RO > tristate "Readonly block device access to MTD devices" > depends on MTD_BLOCK!=y && MTD && BLOCK > > I think though that these limitations are redundant at least for > MTD_BLOCK_RO_BBFREE b/c there might be the cases where there're both > NAND and NOR chips in the system so MTD_BLOCK_RO and > MTD_BLOCK_RO_BBFREE might be needed to be present in the system at > the same time. > > Vitaly > > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ Corrected typo, renamed driver, got rid from redundant dependency. Also I've tested mtdblock_ro_bbfree as module - ok. Interdiff: diff -u mtd-2.6/drivers/mtd/mtdblock_ro_bbfree.c mtd-2.6/drivers/mtd/mtdblock_ro_bbfree.c --- mtd-2.6/drivers/mtd/mtdblock_ro_bbfree.c +++ mtd-2.6/drivers/mtd/mtdblock_ro_bbfree.c @@ -73,7 +73,7 @@ if ((*mtd->block_isbad)(mtd, i * mtd->erasesize) == 0) break; - /* exchausted ? */ + /* exhausted ? */ if (i >= block_top) { printk (KERN_WARNING "map_over_bad_blocks(): no more good blocks!\n"); return (loff_t)-1; @@ -137,7 +137,7 @@ } static struct mtd_blktrans_ops mtdblock_tr = { - .name = "mtdblock", + .name = "mtdblock_bbfree", .major = 258, .part_bits = 0, .readsect = mtdblock_readsect, diff -u mtd-2.6/drivers/mtd/Kconfig mtd-2.6/drivers/mtd/Kconfig --- mtd-2.6/drivers/mtd/Kconfig +++ mtd-2.6/drivers/mtd/Kconfig @@ -199,7 +199,7 @@ config MTD_BLOCK_RO_BBFREE tristate "Readonly bad block free block device access to MTD devices" - depends on MTD_BLOCK!=y && MTD && MTD_BLOCK_RO!=y + 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. Whole patch is attached. [-- Attachment #2: bbfree_mtd_ro.patch --] [-- Type: text/x-patch, Size: 5996 bytes --] drivers/mtd/Kconfig | 7 + drivers/mtd/Makefile | 1 drivers/mtd/mtdblock_ro_bbfree.c | 165 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+) Index: mtd-2.6/drivers/mtd/mtdblock_ro_bbfree.c =================================================================== --- /dev/null +++ mtd-2.6/drivers/mtd/mtdblock_ro_bbfree.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 mtd_block_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 mtd_block_map* dev_cont = container_of(dev, struct mtd_block_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_WARNING "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(0, "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(0, "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 mtdblock_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 mtdblock_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 mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) +{ + struct mtd_block_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 mtdblock_remove_dev(struct mtd_blktrans_dev *dev) +{ + del_mtd_blktrans_dev(dev); + kfree(dev); +} + +static struct mtd_blktrans_ops mtdblock_tr = { + .name = "mtdblock_bbfree", + .major = 258, + .part_bits = 0, + .readsect = mtdblock_readsect, + .writesect = mtdblock_writesect, + .add_mtd = mtdblock_add_mtd, + .remove_dev = mtdblock_remove_dev, + .owner = THIS_MODULE, +}; + +static int __init mtdblock_init(void) +{ + return register_mtd_blktrans(&mtdblock_tr); +} + +static void __exit mtdblock_exit(void) +{ + deregister_mtd_blktrans(&mtdblock_tr); +} + +module_init(mtdblock_init); +module_exit(mtdblock_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_RO_BBFREE) += mtdblock_ro_bbfree.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_RO_BBFREE + tristate "Readonly bad block free block device access to MTD devices" + 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 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 2006-11-22 16:56 ` Konstantin Baydarov @ 2006-12-02 16:41 ` Konstantin Baydarov 2007-09-27 15:05 ` Gregory CLEMENT 0 siblings, 1 reply; 17+ messages in thread From: Konstantin Baydarov @ 2006-12-02 16:41 UTC (permalink / raw) To: Konstantin Baydarov; +Cc: linux-mtd, Vitaly Wool 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 ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] [MTD] BLOCK_RO: Readonly Block Device Layer Over MTD 2006-12-02 16:41 ` Konstantin Baydarov @ 2007-09-27 15:05 ` Gregory CLEMENT 0 siblings, 0 replies; 17+ messages in thread From: Gregory CLEMENT @ 2007-09-27 15:05 UTC (permalink / raw) To: Konstantin Baydarov; +Cc: Vitaly Wool, linux-mtd Hi, this drivers seems pretty good and easily reviewable, so why it hadn't been included in mtd tree ? After some search I had not find any news on this patch, but maybe I missed something. 2006/12/2, Konstantin Baydarov <kbaidarov@dev.rtsoft.ru>: > 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 > > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ > -- Gregory CLEMENT Adeneo 2, chemin du Ruisseau - BP21 69136 Ecully Cedex France Tel : +33-4 72 18 08 40 ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2007-09-27 15:05 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 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 2007-09-27 15:05 ` Gregory CLEMENT
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox