[PATCH] mtd: nandsim: Allow nandsim to re-use persisted data
Richard Weinberger
richard.weinberger at gmail.com
Thu Nov 7 10:12:32 EST 2013
Hi!
On Wed, Sep 25, 2013 at 9:25 PM, Matthew Gabeler-Lee <fastcat at gmail.com> wrote:
> mtd: nandsim: Allow nandsim to re-use persisted data
>
> Add optional (default disabled) module parameter to nandsim to instruct it
> to assume that the cache file already has valid data in it. This allows
> data written to the cache file (or device) to be re-used across reloads of
> the nandsim module, and thus reboots of the host, in much the same way that
> block2mtd allows.
>
> Signed-off-by: Matthew Gabeler-Lee <matthew at beechwoods.com>
> ---
> drivers/mtd/nand/nandsim.c | 42 ++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 38 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
> index bdc1d15..65ac60f 100644
> --- a/drivers/mtd/nand/nandsim.c
> +++ b/drivers/mtd/nand/nandsim.c
> @@ -109,6 +109,7 @@ static unsigned int bitflips = 0;
> static char *gravepages = NULL;
> static unsigned int overridesize = 0;
> static char *cache_file = NULL;
> +static uint cache_file_written = 0;
> static unsigned int bbt;
> static unsigned int bch;
>
> @@ -133,6 +134,7 @@ module_param(bitflips, uint, 0400);
> module_param(gravepages, charp, 0400);
> module_param(overridesize, uint, 0400);
> module_param(cache_file, charp, 0400);
> +module_param(cache_file_written, uint, 0400);
> module_param(bbt, uint, 0400);
> module_param(bch, uint, 0400);
>
> @@ -166,6 +168,7 @@ MODULE_PARM_DESC(overridesize, "Specifies the NAND
> Flash size overriding the I
> "The size is specified in erase blocks and
> as the exponent of a power of two"
> " e.g. 5 means a size of 32 erase blocks");
> MODULE_PARM_DESC(cache_file, "File to use to cache nand pages instead
> of memory");
> +MODULE_PARM_DESC(cache_file_written, "Assume any pages in cache file have
> already been written, use their existing contents");
> MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT
> with marker in data area");
> MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits
> should "
> "be correctable in 512-byte blocks");
> @@ -592,6 +595,9 @@ static int alloc_device(struct nandsim *ns)
> err = -ENOMEM;
> goto err_close;
> }
> + if (cache_file_written) {
> + memset(ns->pages_written, 0xFF, ns->geom.pgnum);
> + }
Hmm, that's a very ugly hack.
It will slow down nandsim because now it will ask the file cache every time.
If you want persistent storage we'd need a sane file format with header
which contains the page_written bitmask, the nand geometry, etc....
> ns->file_buf = kmalloc(ns->geom.pgszoob, GFP_KERNEL);
> if (!ns->file_buf) {
> NS_ERR("alloc_device: unable to allocate file
> buf\n");
> @@ -1484,7 +1490,17 @@ static void read_page(struct nandsim *ns, int num)
> pos = (loff_t)NS_RAW_OFFSET(ns) + ns->regs.off;
> tx = read_file(ns, ns->cfile, ns->buf.byte, num,
> pos);
> if (tx != num) {
> - NS_ERR("read_page: read error for page %d
> ret %ld\n", ns->regs.row, (long)tx);
> + if (ns->pages_written[ns->regs.row] == 0xFF)
> {
> + NS_WARN("read_page: read error
> assuming unwritten for page %d ret %ld\n", ns->regs.row, (long)tx);
> + ns->pages_written[ns->regs.row] = 0;
> + memset(ns->buf.byte, 0xFF, num);
> + tx = write_file(ns, ns->cfile,
> ns->buf.byte, num, pos);
> + if (tx != num) {
> + NS_ERR("read_page: write
> error for page %d ret %ld\n", ns->regs.row, (long)tx);
> + }
> + } else {
> + NS_ERR("read_page: read error for
> page %d ret %ld\n", ns->regs.row, (long)tx);
> + }
> return;
> }
> do_bit_flips(ns, num);
> @@ -1515,11 +1531,22 @@ static void erase_sector(struct nandsim *ns)
> int i;
>
> if (ns->cfile) {
> - for (i = 0; i < ns->geom.pgsec; i++)
> + loff_t pos;
> + ssize_t tx;
> + + memset(ns->file_buf, 0xff, ns->geom.pgszoob);
> + for (i = 0; i < ns->geom.pgsec; i++) {
> if (__test_and_clear_bit(ns->regs.row + i,
> ns->pages_written)) {
> NS_DBG("erase_sector: freeing page %d\n",
> ns->regs.row + i);
> + pos = (loff_t)(ns->regs.row + i) *
> ns->geom.pgszoob;
> + tx = write_file(ns, ns->cfile, ns->file_buf,
> ns->geom.pgszoob, pos);
> + if (tx != ns->geom.pgszoob) {
> + NS_ERR("erase_sector: write error
> for page %d ret %ld\n", ns->regs.row, (long)tx);
> + }
> }
> + ns->pages_written[ns->regs.row + i] = 0;
> + }
> return;
> }
>
> @@ -1558,8 +1585,15 @@ static int prog_page(struct nandsim *ns, int num)
> all = 0;
> tx = read_file(ns, ns->cfile, pg_off, num, off);
> if (tx != num) {
> - NS_ERR("prog_page: read error for page %d
> ret %ld\n", ns->regs.row, (long)tx);
> - return -1;
> + if (ns->pages_written[ns->regs.row] == 0xFF)
> {
> + NS_WARN("prog_page: read error
> assuming unwritten for page %d ret %ld\n", ns->regs.row, (long)tx);
> + ns->pages_written[ns->regs.row] = 0;
> + all = 1;
> + memset(ns->file_buf, 0xff,
> ns->geom.pgszoob);
> + } else {
> + NS_ERR("prog_page: read error for
> page %d ret %ld\n", ns->regs.row, (long)tx);
> + return -1;
> + }
> }
> }
> for (i = 0; i < num; i++)
> --
> 1.8.4.rc3
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
--
Thanks,
//richard
More information about the linux-mtd
mailing list