Mercurial > yaffs-ecoscentric
annotate yaffs_packedtags2.c @ 255:467bb4a77339
Improve handling of ecc on tags
| author | charles |
|---|---|
| date | Fri, 16 Jan 2009 00:45:47 +0000 |
| parents | fad21fd1971d |
| children | c8620405d086 |
| rev | line source |
|---|---|
| 15 | 1 /* |
| 174 | 2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. |
| 15 | 3 * |
| 174 | 4 * Copyright (C) 2002-2007 Aleph One Ltd. |
| 5 * for Toby Churchill Ltd and Brightstar Engineering | |
| 15 | 6 * |
| 7 * Created by Charles Manning <charles@aleph1.co.uk> | |
| 8 * | |
| 174 | 9 * This program is free software; you can redistribute it and/or modify |
| 10 * it under the terms of the GNU General Public License version 2 as | |
| 11 * published by the Free Software Foundation. | |
| 15 | 12 */ |
| 79 | 13 |
| 6 | 14 #include "yaffs_packedtags2.h" |
| 15 #include "yportenv.h" | |
| 15 | 16 #include "yaffs_tagsvalidity.h" |
| 17 | |
| 79 | 18 /* This code packs a set of extended tags into a binary structure for |
| 19 * NAND storage | |
| 20 */ | |
| 15 | 21 |
| 79 | 22 /* Some of the information is "extra" struff which can be packed in to |
| 23 * speed scanning | |
| 24 * This is defined by having the EXTRA_HEADER_INFO_FLAG set. | |
| 25 */ | |
| 15 | 26 |
| 79 | 27 /* Extra flags applied to chunkId */ |
| 15 | 28 |
| 29 #define EXTRA_HEADER_INFO_FLAG 0x80000000 | |
| 30 #define EXTRA_SHRINK_FLAG 0x40000000 | |
| 50 | 31 #define EXTRA_SHADOWS_FLAG 0x20000000 |
| 32 #define EXTRA_SPARE_FLAGS 0x10000000 | |
| 15 | 33 |
| 34 #define ALL_EXTRA_FLAGS 0xF0000000 | |
| 35 | |
| 79 | 36 /* Also, the top 4 bits of the object Id are set to the object type. */ |
| 15 | 37 #define EXTRA_OBJECT_TYPE_SHIFT (28) |
| 38 #define EXTRA_OBJECT_TYPE_MASK ((0x0F) << EXTRA_OBJECT_TYPE_SHIFT) | |
| 39 | |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
40 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
41 static void yaffs_DumpPackedTags2TagsPart(const yaffs_PackedTags2TagsPart * ptt) |
| 7 | 42 { |
| 79 | 43 T(YAFFS_TRACE_MTD, |
| 44 (TSTR("packed tags obj %d chunk %d byte %d seq %d" TENDSTR), | |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
45 ptt->objectId, ptt->chunkId, ptt->byteCount, |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
46 ptt->sequenceNumber)); |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
47 } |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
48 static void yaffs_DumpPackedTags2(const yaffs_PackedTags2 * pt) |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
49 { |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
50 yaffs_DumpPackedTags2TagsPart(&pt->t); |
| 7 | 51 } |
| 6 | 52 |
| 79 | 53 static void yaffs_DumpTags2(const yaffs_ExtendedTags * t) |
| 7 | 54 { |
| 79 | 55 T(YAFFS_TRACE_MTD, |
| 56 (TSTR | |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
57 ("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte %d del %d ser %d seq %d" |
| 79 | 58 TENDSTR), t->eccResult, t->blockBad, t->chunkUsed, t->objectId, |
| 59 t->chunkId, t->byteCount, t->chunkDeleted, t->serialNumber, | |
| 60 t->sequenceNumber)); | |
| 61 | |
| 7 | 62 } |
| 63 | |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
64 void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart * ptt, const yaffs_ExtendedTags * t) |
| 6 | 65 { |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
66 ptt->chunkId = t->chunkId; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
67 ptt->sequenceNumber = t->sequenceNumber; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
68 ptt->byteCount = t->byteCount; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
69 ptt->objectId = t->objectId; |
| 79 | 70 |
| 71 if (t->chunkId == 0 && t->extraHeaderInfoAvailable) { | |
| 72 /* Store the extra header info instead */ | |
| 73 /* We save the parent object in the chunkId */ | |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
74 ptt->chunkId = EXTRA_HEADER_INFO_FLAG |
| 79 | 75 | t->extraParentObjectId; |
| 76 if (t->extraIsShrinkHeader) { | |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
77 ptt->chunkId |= EXTRA_SHRINK_FLAG; |
| 15 | 78 } |
| 79 | 79 if (t->extraShadows) { |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
80 ptt->chunkId |= EXTRA_SHADOWS_FLAG; |
| 50 | 81 } |
| 79 | 82 |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
83 ptt->objectId &= ~EXTRA_OBJECT_TYPE_MASK; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
84 ptt->objectId |= |
| 79 | 85 (t->extraObjectType << EXTRA_OBJECT_TYPE_SHIFT); |
| 86 | |
| 87 if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) { | |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
88 ptt->byteCount = t->extraEquivalentObjectId; |
| 79 | 89 } else if (t->extraObjectType == YAFFS_OBJECT_TYPE_FILE) { |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
90 ptt->byteCount = t->extraFileLength; |
| 79 | 91 } else { |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
92 ptt->byteCount = 0; |
| 15 | 93 } |
| 94 } | |
| 79 | 95 |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
96 yaffs_DumpPackedTags2TagsPart(ptt); |
| 7 | 97 yaffs_DumpTags2(t); |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
98 } |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
99 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
100 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
101 void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t) |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
102 { |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
103 yaffs_PackTags2TagsPart(&pt->t,t); |
| 79 | 104 |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
15
diff
changeset
|
105 #ifndef YAFFS_IGNORE_TAGS_ECC |
| 79 | 106 { |
| 107 yaffs_ECCCalculateOther((unsigned char *)&pt->t, | |
| 108 sizeof(yaffs_PackedTags2TagsPart), | |
| 109 &pt->ecc); | |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
15
diff
changeset
|
110 } |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
15
diff
changeset
|
111 #endif |
| 6 | 112 } |
| 113 | |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
114 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
115 void yaffs_UnpackTags2TagsPart(yaffs_ExtendedTags * t, yaffs_PackedTags2TagsPart * ptt) |
| 6 | 116 { |
| 117 | |
| 79 | 118 memset(t, 0, sizeof(yaffs_ExtendedTags)); |
| 119 | |
| 15 | 120 yaffs_InitialiseTags(t); |
| 79 | 121 |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
122 if (ptt->sequenceNumber != 0xFFFFFFFF) { |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
123 t->blockBad = 0; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
124 t->chunkUsed = 1; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
125 t->objectId = ptt->objectId; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
126 t->chunkId = ptt->chunkId; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
127 t->byteCount = ptt->byteCount; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
128 t->chunkDeleted = 0; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
129 t->serialNumber = 0; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
130 t->sequenceNumber = ptt->sequenceNumber; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
131 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
132 /* Do extra header info stuff */ |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
133 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
134 if (ptt->chunkId & EXTRA_HEADER_INFO_FLAG) { |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
135 t->chunkId = 0; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
136 t->byteCount = 0; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
137 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
138 t->extraHeaderInfoAvailable = 1; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
139 t->extraParentObjectId = |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
140 ptt->chunkId & (~(ALL_EXTRA_FLAGS)); |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
141 t->extraIsShrinkHeader = |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
142 (ptt->chunkId & EXTRA_SHRINK_FLAG) ? 1 : 0; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
143 t->extraShadows = |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
144 (ptt->chunkId & EXTRA_SHADOWS_FLAG) ? 1 : 0; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
145 t->extraObjectType = |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
146 ptt->objectId >> EXTRA_OBJECT_TYPE_SHIFT; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
147 t->objectId &= ~EXTRA_OBJECT_TYPE_MASK; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
148 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
149 if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) { |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
150 t->extraEquivalentObjectId = ptt->byteCount; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
151 } else { |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
152 t->extraFileLength = ptt->byteCount; |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
153 } |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
154 } |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
155 } |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
156 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
157 yaffs_DumpPackedTags2TagsPart(ptt); |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
158 yaffs_DumpTags2(t); |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
159 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
160 } |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
161 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
162 |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
163 void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt) |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
164 { |
|
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
165 |
| 255 | 166 yaffs_ECCResult eccResult = YAFFS_ECC_RESULT_NO_ERROR; |
| 167 | |
| 79 | 168 if (pt->t.sequenceNumber != 0xFFFFFFFF) { |
| 169 /* Page is in use */ | |
| 255 | 170 #ifndef YAFFS_IGNORE_TAGS_ECC |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
15
diff
changeset
|
171 { |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
15
diff
changeset
|
172 yaffs_ECCOther ecc; |
| 148 | 173 int result; |
| 79 | 174 yaffs_ECCCalculateOther((unsigned char *)&pt->t, |
| 175 sizeof | |
| 176 (yaffs_PackedTags2TagsPart), | |
| 177 &ecc); | |
| 148 | 178 result = |
| 79 | 179 yaffs_ECCCorrectOther((unsigned char *)&pt->t, |
| 180 sizeof | |
| 181 (yaffs_PackedTags2TagsPart), | |
| 182 &pt->ecc, &ecc); | |
| 148 | 183 switch(result){ |
|
205
f95fdc6123fb
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey
parents:
177
diff
changeset
|
184 case 0: |
| 255 | 185 eccResult = YAFFS_ECC_RESULT_NO_ERROR; |
| 148 | 186 break; |
|
205
f95fdc6123fb
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey
parents:
177
diff
changeset
|
187 case 1: |
| 255 | 188 eccResult = YAFFS_ECC_RESULT_FIXED; |
| 148 | 189 break; |
| 190 case -1: | |
| 255 | 191 eccResult = YAFFS_ECC_RESULT_UNFIXED; |
| 148 | 192 break; |
| 193 default: | |
| 255 | 194 eccResult = YAFFS_ECC_RESULT_UNKNOWN; |
| 148 | 195 } |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
15
diff
changeset
|
196 } |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
15
diff
changeset
|
197 #endif |
| 6 | 198 } |
| 7 | 199 |
| 255 | 200 yaffs_UnpackTags2TagsPart(t,&pt->t); |
| 201 | |
| 202 t->eccResult = eccResult; | |
| 203 | |
| 7 | 204 yaffs_DumpPackedTags2(pt); |
| 205 yaffs_DumpTags2(t); | |
| 206 | |
| 6 | 207 } |
|
211
fad21fd1971d
Check in inband tags, some extra yaffs direct functions and some other changes
charles
parents:
205
diff
changeset
|
208 |
