From 1ffa02489a63129109b66774681c94fe0a8a946a Mon Sep 17 00:00:00 2001 From: charles Date: Wed, 14 Oct 2009 00:01:56 +0000 Subject: [PATCH] Allow the disabling of tags ECC --- Kconfig | 12 ++++++++++++ direct/yaffs_fileem2k.c | 8 ++++---- direct/yaffs_ramem2k.c | 6 +++--- moduleconfig.h | 4 ++++ yaffs_fs.c | 22 ++++++++++++++++++++-- yaffs_guts.h | 3 ++- yaffs_mtdif2.c | 24 +++++++++++++++--------- yaffs_packedtags2.c | 41 ++++++++++++++++------------------------- yaffs_packedtags2.h | 4 ++-- 9 files changed, 78 insertions(+), 46 deletions(-) diff --git a/Kconfig b/Kconfig index c0e545b..1d3bb71 100644 --- a/Kconfig +++ b/Kconfig @@ -90,6 +90,18 @@ config YAFFS_AUTO_YAFFS2 If unsure, say Y. +config YAFFS_DISABLE_TAGS_ECC + bool "Disable YAFFS from doing ECC on tags by default" + depends on YAFFS_FS && YAFFS_YAFFS2 + default n + help + This defaults Yaffs to using its own ECC calculations on tags instead of + just relying on the MTD. + This behavior can also be overridden with tags_ecc_on and + tags_ecc_off mount options. + + If unsure, say N. + config YAFFS_DISABLE_LAZY_LOAD bool "Disable lazy loading" depends on YAFFS_YAFFS2 diff --git a/direct/yaffs_fileem2k.c b/direct/yaffs_fileem2k.c index 1050276..cfe992e 100644 --- a/direct/yaffs_fileem2k.c +++ b/direct/yaffs_fileem2k.c @@ -16,7 +16,7 @@ * This is only intended as test code to test persistence etc. */ -const char *yaffs_flashif2_c_version = "$Id: yaffs_fileem2k.c,v 1.18 2009-01-16 02:26:56 charles Exp $"; +const char *yaffs_flashif2_c_version = "$Id: yaffs_fileem2k.c,v 1.19 2009-10-14 00:01:57 charles Exp $"; #include "yportenv.h" @@ -258,7 +258,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u else { yaffs_PackedTags2 pt; - yaffs_PackTags2(&pt,tags); + yaffs_PackTags2(dev,&pt,tags); __u8 * ptab = (__u8 *)&pt; nRead = read(h,localBuffer,sizeof(pt)); @@ -336,7 +336,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u else { yaffs_PackedTags2 pt; - yaffs_PackTags2(&pt,tags); + yaffs_PackTags2(dev,&pt,tags); __u8 * ptab = (__u8 *)&pt; nRead = read(h,localBuffer,sizeof(pt)); @@ -471,7 +471,7 @@ int yflash2_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *d { yaffs_PackedTags2 pt; nread= read(h,&pt,sizeof(pt)); - yaffs_UnpackTags2(tags,&pt); + yaffs_UnpackTags2(dev,tags,&pt); #ifdef SIMULATE_FAILURES if((chunkInNAND >> 6) == 100) { if(fail300 && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR){ diff --git a/direct/yaffs_ramem2k.c b/direct/yaffs_ramem2k.c index b496cc6..767dcea 100644 --- a/direct/yaffs_ramem2k.c +++ b/direct/yaffs_ramem2k.c @@ -16,7 +16,7 @@ */ -const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.4 2008-05-05 07:58:58 charles Exp $"; +const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.5 2009-10-14 00:01:57 charles Exp $"; #ifndef __KERNEL__ #define CONFIG_YAFFS_RAM_ENABLED @@ -220,7 +220,7 @@ int nandemul2k_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const { x = &ned.block[blk]->page[pg]->data[PAGE_DATA_SIZE]; - yaffs_PackTags2((yaffs_PackedTags2 *)x,tags); + yaffs_PackTags2(dev,(yaffs_PackedTags2 *)x,tags); } @@ -256,7 +256,7 @@ int nandemul2k_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 { x = &ned.block[blk]->page[pg]->data[PAGE_DATA_SIZE]; - yaffs_UnpackTags2(tags,(yaffs_PackedTags2 *)x); + yaffs_UnpackTags2(dev,tags,(yaffs_PackedTags2 *)x); } return YAFFS_OK; diff --git a/moduleconfig.h b/moduleconfig.h index a344baf..99c9f6a 100644 --- a/moduleconfig.h +++ b/moduleconfig.h @@ -29,6 +29,10 @@ /* Meaning: Yaffs does its own ECC, rather than using MTD ECC */ /* #define CONFIG_YAFFS_DOES_ECC */ +/* Default: Selected */ +/* Meaning: Yaffs does its own ECC on tags for packed tags rather than use mtd */ +#define CONFIG_YAFFS_DOES_TAGS_ECC + /* Default: Not selected */ /* Meaning: ECC byte order is 'wrong'. Only meaningful if */ /* CONFIG_YAFFS_DOES_ECC is set */ diff --git a/yaffs_fs.c b/yaffs_fs.c index 3fd94df..a51dc20 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -32,7 +32,7 @@ */ const char *yaffs_fs_c_version = - "$Id: yaffs_fs.c,v 1.83 2009-09-23 23:24:55 charles Exp $"; + "$Id: yaffs_fs.c,v 1.84 2009-10-14 00:01:56 charles Exp $"; extern const char *yaffs_guts_c_version; #include @@ -1812,6 +1812,8 @@ typedef struct { int skip_checkpoint_read; int skip_checkpoint_write; int no_cache; + int tags_ecc_on; + int tags_ecc_overridden; } yaffs_options; #define MAX_OPT_LEN 20 @@ -1827,6 +1829,9 @@ static int yaffs_parse_options(yaffs_options *options, const char *options_str) memset(cur_opt, 0, MAX_OPT_LEN + 1); p = 0; + while(*options_str == ',') + options_str++; + while (*options_str && *options_str != ',') { if (p < MAX_OPT_LEN) { cur_opt[p] = *options_str; @@ -1837,7 +1842,13 @@ static int yaffs_parse_options(yaffs_options *options, const char *options_str) if (!strcmp(cur_opt, "inband-tags")) options->inband_tags = 1; - else if (!strcmp(cur_opt, "no-cache")) + else if (!strcmp(cur_opt, "tags-ecc-off")){ + options->tags_ecc_on = 0; + options->tags_ecc_overridden=1; + } else if (!strcmp(cur_opt, "tags-ecc-on")){ + options->tags_ecc_on = 1; + options->tags_ecc_overridden = 1; + } else if (!strcmp(cur_opt, "no-cache")) options->no_cache = 1; else if (!strcmp(cur_opt, "no-checkpoint-read")) options->skip_checkpoint_read = 1; @@ -2053,6 +2064,12 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion, dev->nShortOpCaches = (options.no_cache) ? 0 : 10; dev->inbandTags = options.inband_tags; +#ifdef CONFIG_YAFFS_DISABLE_TAGS_ECC + dev->noTagsECC = 1; +#endif + if(options.tags_ecc_overridden) + dev->noTagsECC = !options.tags_ecc_on; + /* ... and the functions. */ if (yaffsVersion == 2) { dev->writeChunkWithTagsToNAND = @@ -2289,6 +2306,7 @@ static char *yaffs_dump_dev(char *buf, yaffs_Device * dev) buf += sprintf(buf, "nBackgroudDeletions %d\n", dev->nBackgroundDeletions); buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC); + buf += sprintf(buf, "noTagsECC.......... %d\n", dev->noTagsECC); buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2); buf += sprintf(buf, "inbandTags......... %d\n", dev->inbandTags); diff --git a/yaffs_guts.h b/yaffs_guts.h index cb8d8ec..853fea6 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -557,7 +557,8 @@ struct yaffs_DeviceStruct { int useHeaderFileSize; /* Flag to determine if we should use file sizes from the header */ - int useNANDECC; /* Flag to decide whether or not to use NANDECC */ + int useNANDECC; /* Flag to decide whether or not to use NANDECC on data (yaffs1) */ + int noTagsECC; /* Flag to decide whether or not to do ECC on packed tags (yaffs2) */ void *genericDevice; /* Pointer to device context * On an mtd this holds the mtd pointer. diff --git a/yaffs_mtdif2.c b/yaffs_mtdif2.c index 77504ba..918f8de 100644 --- a/yaffs_mtdif2.c +++ b/yaffs_mtdif2.c @@ -14,7 +14,7 @@ /* mtd interface for YAFFS2 */ const char *yaffs_mtdif2_c_version = - "$Id: yaffs_mtdif2.c,v 1.23 2009-03-06 17:20:53 wookey Exp $"; + "$Id: yaffs_mtdif2.c,v 1.24 2009-10-14 00:01:57 charles Exp $"; #include "yportenv.h" @@ -47,6 +47,9 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND, yaffs_PackedTags2 pt; + int packed_tags_size = dev->noTagsECC ? sizeof(pt.t) : sizeof(pt); + void * packed_tags_ptr = dev->noTagsECC ? (void *) &pt.t : (void *)&pt; + T(YAFFS_TRACE_MTD, (TSTR ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p" @@ -66,22 +69,22 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND, pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk); yaffs_PackTags2TagsPart(pt2tp, tags); } else - yaffs_PackTags2(&pt, tags); + yaffs_PackTags2(dev, &pt, tags); #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) ops.mode = MTD_OOB_AUTO; - ops.ooblen = (dev->inbandTags) ? 0 : sizeof(pt); + ops.ooblen = (dev->inbandTags) ? 0 : packed_tags_size; ops.len = dev->totalBytesPerChunk; ops.ooboffs = 0; ops.datbuf = (__u8 *)data; - ops.oobbuf = (dev->inbandTags) ? NULL : (void *)&pt; + ops.oobbuf = (dev->inbandTags) ? NULL : packed_tags_ptr; retval = mtd->write_oob(mtd, addr, &ops); #else if (!dev->inbandTags) { retval = mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk, - &dummy, data, (__u8 *) &pt, NULL); + &dummy, data, (__u8 *) packed_tags_ptr, NULL); } else { retval = mtd->write(mtd, addr, dev->totalBytesPerChunk, &dummy, @@ -110,6 +113,9 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, yaffs_PackedTags2 pt; + int packed_tags_size = dev->noTagsECC ? sizeof(pt.t) : sizeof(pt); + void * packed_tags_ptr = dev->noTagsECC ? (void *) &pt.t: (void *)&pt; + T(YAFFS_TRACE_MTD, (TSTR ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p" @@ -132,8 +138,8 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, &dummy, data); else if (tags) { ops.mode = MTD_OOB_AUTO; - ops.ooblen = sizeof(pt); - ops.len = data ? dev->nDataBytesPerChunk : sizeof(pt); + ops.ooblen = packed_tags_size; + ops.len = data ? dev->nDataBytesPerChunk : packed_tags_size; ops.ooboffs = 0; ops.datbuf = data; ops.oobbuf = dev->spareBuffer; @@ -166,8 +172,8 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, } } else { if (tags) { - memcpy(&pt, dev->spareBuffer, sizeof(pt)); - yaffs_UnpackTags2(tags, &pt); + memcpy(packed_tags_ptr, dev->spareBuffer, packed_tags_size); + yaffs_UnpackTags2(dev, tags, &pt); } } diff --git a/yaffs_packedtags2.c b/yaffs_packedtags2.c index a78c03c..e0c5586 100644 --- a/yaffs_packedtags2.c +++ b/yaffs_packedtags2.c @@ -96,17 +96,14 @@ void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart *ptt, } -void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t) +void yaffs_PackTags2(yaffs_Device *dev, yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t) { yaffs_PackTags2TagsPart(&pt->t, t); -#ifndef YAFFS_IGNORE_TAGS_ECC - { + if(!dev->noTagsECC) yaffs_ECCCalculateOther((unsigned char *)&pt->t, sizeof(yaffs_PackedTags2TagsPart), &pt->ecc); - } -#endif } @@ -158,27 +155,24 @@ void yaffs_UnpackTags2TagsPart(yaffs_ExtendedTags *t, } -void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt) +void yaffs_UnpackTags2(yaffs_Device *dev, yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt) { yaffs_ECCResult eccResult = YAFFS_ECC_RESULT_NO_ERROR; - if (pt->t.sequenceNumber != 0xFFFFFFFF) { - /* Page is in use */ -#ifndef YAFFS_IGNORE_TAGS_ECC - { - yaffs_ECCOther ecc; - int result; - yaffs_ECCCalculateOther((unsigned char *)&pt->t, - sizeof - (yaffs_PackedTags2TagsPart), - &ecc); - result = - yaffs_ECCCorrectOther((unsigned char *)&pt->t, - sizeof - (yaffs_PackedTags2TagsPart), - &pt->ecc, &ecc); - switch (result) { + if (pt->t.sequenceNumber != 0xFFFFFFFF && + !dev->noTagsECC){ + /* Chunk is in use and we need to do ECC */ + + yaffs_ECCOther ecc; + int result; + yaffs_ECCCalculateOther((unsigned char *)&pt->t, + sizeof(yaffs_PackedTags2TagsPart), + &ecc); + result = yaffs_ECCCorrectOther((unsigned char *)&pt->t, + sizeof(yaffs_PackedTags2TagsPart), + &pt->ecc, &ecc); + switch (result) { case 0: eccResult = YAFFS_ECC_RESULT_NO_ERROR; break; @@ -190,9 +184,7 @@ void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt) break; default: eccResult = YAFFS_ECC_RESULT_UNKNOWN; - } } -#endif } yaffs_UnpackTags2TagsPart(t, &pt->t); @@ -201,6 +193,5 @@ void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt) yaffs_DumpPackedTags2(pt); yaffs_DumpTags2(t); - } diff --git a/yaffs_packedtags2.h b/yaffs_packedtags2.h index ec30f84..d90c6cb 100644 --- a/yaffs_packedtags2.h +++ b/yaffs_packedtags2.h @@ -34,8 +34,8 @@ typedef struct { } yaffs_PackedTags2; /* Full packed tags with ECC, used for oob tags */ -void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t); -void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt); +void yaffs_PackTags2(yaffs_Device *dev, yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t); +void yaffs_UnpackTags2(yaffs_Device *dev, yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt); /* Only the tags part (no ECC for use with inband tags */ void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart *pt, const yaffs_ExtendedTags *t); -- 2.30.2