Mercurial > yaffs-ecoscentric
annotate yaffs_guts.h @ 27:ae8aefd82ff7
Prevent recursive gc
| author | charles |
|---|---|
| date | Tue, 26 Jul 2005 04:05:28 +0100 |
| parents | 4ebabd859f38 |
| children | bd762956951e |
| rev | line source |
|---|---|
| 0 | 1 /* |
| 15 | 2 * YAFFS: Yet another FFS. A NAND-flash specific file system. |
| 0 | 3 * yaffs_guts.h: Configuration etc for yaffs_guts |
| 4 * | |
| 5 * Copyright (C) 2002 Aleph One Ltd. | |
| 6 * for Toby Churchill Ltd and Brightstar Engineering | |
| 7 * | |
| 8 * Created by Charles Manning <charles@aleph1.co.uk> | |
| 9 * | |
| 10 * This program is free software; you can redistribute it and/or modify | |
| 11 * it under the terms of the GNU Lesser General Public License version 2.1 as | |
| 12 * published by the Free Software Foundation. | |
| 13 * | |
| 14 * | |
| 15 * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. | |
| 16 * | |
| 17 * $Id$ | |
| 18 */ | |
| 19 | |
| 20 #ifndef __YAFFS_GUTS_H__ | |
| 21 #define __YAFFS_GUTS_H__ | |
| 22 | |
| 23 #include "devextras.h" | |
| 24 #include "yportenv.h" | |
| 25 | |
| 26 #define YAFFS_OK 1 | |
| 27 #define YAFFS_FAIL 0 | |
| 28 | |
| 29 // Give us a Y=0x59, | |
| 30 // Give us an A=0x41, | |
| 31 // Give us an FF=0xFF | |
| 32 // Give us an S=0x53 | |
| 33 // And what have we got... | |
| 34 #define YAFFS_MAGIC 0x5941FF53 | |
| 35 | |
| 36 #define YAFFS_NTNODES_LEVEL0 16 | |
| 37 #define YAFFS_TNODES_LEVEL0_BITS 4 | |
| 38 #define YAFFS_TNODES_LEVEL0_MASK 0xf | |
| 39 | |
| 40 #define YAFFS_NTNODES_INTERNAL (YAFFS_NTNODES_LEVEL0 / 2) | |
| 41 #define YAFFS_TNODES_INTERNAL_BITS (YAFFS_TNODES_LEVEL0_BITS - 1) | |
| 42 #define YAFFS_TNODES_INTERNAL_MASK 0x7 | |
| 43 #define YAFFS_TNODES_MAX_LEVEL 6 | |
| 44 | |
| 45 #ifndef CONFIG_YAFFS_NO_YAFFS1 | |
| 46 #define YAFFS_BYTES_PER_SPARE 16 | |
| 47 #define YAFFS_BYTES_PER_CHUNK 512 | |
| 48 #define YAFFS_CHUNK_SIZE_SHIFT 9 | |
| 49 #define YAFFS_CHUNKS_PER_BLOCK 32 | |
| 50 #define YAFFS_BYTES_PER_BLOCK (YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK) | |
| 51 #endif | |
| 52 | |
| 7 | 53 #define YAFFS_MIN_YAFFS2_CHUNK_SIZE 1024 |
| 54 #define YAFFS_MIN_YAFFS2_SPARE_SIZE 32 | |
| 55 | |
| 0 | 56 #define YAFFS_MAX_CHUNK_ID 0x000FFFFF |
| 57 | |
| 58 #define YAFFS_UNUSED_OBJECT_ID 0x0003FFFF | |
| 59 | |
| 60 #define YAFFS_ALLOCATION_NOBJECTS 100 | |
| 61 #define YAFFS_ALLOCATION_NTNODES 100 | |
| 62 #define YAFFS_ALLOCATION_NLINKS 100 | |
| 63 | |
| 64 #define YAFFS_NOBJECT_BUCKETS 256 | |
| 65 | |
| 66 | |
| 67 #define YAFFS_OBJECT_SPACE 0x40000 | |
| 68 | |
| 69 #ifdef CONFIG_YAFFS_UNICODE | |
| 70 #define YAFFS_MAX_NAME_LENGTH 127 | |
| 71 #define YAFFS_MAX_ALIAS_LENGTH 79 | |
| 72 #else | |
| 73 #define YAFFS_MAX_NAME_LENGTH 255 | |
| 74 #define YAFFS_MAX_ALIAS_LENGTH 159 | |
| 75 #endif | |
| 76 | |
| 77 #define YAFFS_SHORT_NAME_LENGTH 15 | |
| 78 | |
| 79 | |
| 80 #define YAFFS_OBJECTID_ROOT 1 | |
| 81 #define YAFFS_OBJECTID_LOSTNFOUND 2 | |
| 82 #define YAFFS_OBJECTID_UNLINKED 3 | |
| 83 #define YAFFS_OBJECTID_DELETED 4 | |
| 84 | |
| 85 #define YAFFS_MAX_SHORT_OP_CACHES 20 | |
| 86 | |
| 87 #define YAFFS_N_TEMP_BUFFERS 4 | |
| 88 | |
| 89 // Sequence numbers are used in YAFFS2 to determine block allocation order. | |
| 90 // The range is limited slightly to help distinguish bad numbers from good. | |
| 91 // This also allows us to perhaps in the future use special numbers for | |
| 92 // special purposes. | |
| 93 // EFFFFF00 allows the allocation of 8 blocks per second (~1Mbytes) for 15 years, | |
| 94 // and is a larger number than the lifetime of a 2GB device. | |
| 95 | |
| 96 #define YAFFS_LOWEST_SEQUENCE_NUMBER 0x00001000 | |
| 97 #define YAFFS_HIGHEST_SEQUENCE_NUMBER 0xEFFFFF00 | |
| 98 | |
| 99 | |
| 100 // ChunkCache is used for short read/write operations. | |
| 101 typedef struct | |
| 102 { | |
| 103 struct yaffs_ObjectStruct *object; | |
| 104 int chunkId; | |
| 105 int lastUse; | |
| 106 int dirty; | |
| 107 int nBytes; // Only valid if the cache is dirty | |
| 108 int locked; // Can't push out or flush while locked.. | |
| 4 | 109 #ifdef CONFIG_YAFFS_YAFFS2 |
| 0 | 110 __u8 *data; |
| 111 #else | |
| 112 __u8 data[YAFFS_BYTES_PER_CHUNK]; | |
| 113 #endif | |
| 114 } yaffs_ChunkCache; | |
| 115 | |
| 116 | |
| 117 #ifndef CONFIG_YAFFS_NO_YAFFS1 | |
| 118 // Tags structures in RAM | |
| 119 // NB This uses bitfield. Bitfields should not straddle a u32 boundary otherwise | |
| 120 // the structure size will get blown out. | |
| 121 | |
| 122 typedef struct | |
| 123 { | |
| 124 unsigned chunkId:20; | |
| 125 unsigned serialNumber:2; | |
| 126 unsigned byteCount:10; | |
| 127 unsigned objectId:18; | |
| 128 unsigned ecc:12; | |
| 129 unsigned unusedStuff:2; | |
| 130 | |
| 131 } yaffs_Tags; | |
| 132 | |
| 133 typedef union | |
| 134 { | |
| 135 yaffs_Tags asTags; | |
| 136 __u8 asBytes[8]; | |
| 137 } yaffs_TagsUnion; | |
| 138 | |
| 139 #endif | |
| 140 | |
| 141 typedef enum | |
| 142 { | |
| 143 YAFFS_ECC_RESULT_UNKNOWN, | |
| 144 YAFFS_ECC_RESULT_NO_ERROR, | |
| 145 YAFFS_ECC_RESULT_FIXED, | |
| 146 YAFFS_ECC_RESULT_UNFIXED | |
| 147 } yaffs_ECCResult; | |
| 148 | |
| 15 | 149 typedef enum |
| 150 { | |
| 151 YAFFS_OBJECT_TYPE_UNKNOWN, | |
| 152 YAFFS_OBJECT_TYPE_FILE, | |
| 153 YAFFS_OBJECT_TYPE_SYMLINK, | |
| 154 YAFFS_OBJECT_TYPE_DIRECTORY, | |
| 155 YAFFS_OBJECT_TYPE_HARDLINK, | |
| 156 YAFFS_OBJECT_TYPE_SPECIAL | |
| 157 } yaffs_ObjectType; | |
| 158 | |
| 159 | |
| 0 | 160 typedef struct |
| 161 { | |
| 162 | |
| 163 unsigned validMarker0; | |
| 164 unsigned chunkUsed; // Status of the chunk: used or unused | |
| 165 unsigned objectId; // If 0 then this is not part of an object (unused) | |
| 15 | 166 unsigned chunkId; // If 0 then this is a header, else a data chunk |
| 0 | 167 unsigned byteCount; // Only valid for data chunks |
| 15 | 168 |
| 169 | |
| 0 | 170 // The following stuff only has meaning when we read |
| 171 yaffs_ECCResult eccResult; // Only valid when we read. | |
| 172 unsigned blockBad; // Only valid on reading | |
| 173 | |
| 174 // YAFFS 1 stuff | |
| 175 unsigned chunkDeleted; // The chunk is marked deleted | |
| 176 unsigned serialNumber; // Yaffs1 2-bit serial number | |
| 177 | |
| 178 // YAFFS2 stuff | |
| 179 unsigned sequenceNumber; // The sequence number of this block | |
| 180 | |
| 15 | 181 // Extra info if this is an object header (YAFFS2 only) |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
182 |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
183 unsigned extraHeaderInfoAvailable; // There is extra info available if this is not zero |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
184 unsigned extraParentObjectId; // The parent object |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
185 unsigned extraIsShrinkHeader; // Is it a shrink header? |
| 15 | 186 |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
187 yaffs_ObjectType extraObjectType; // What object type? |
| 15 | 188 |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
189 unsigned extraFileLength; // Length if it is a file |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
190 unsigned extraEquivalentObjectId; // Equivalent object Id if it is a hard link |
| 15 | 191 |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
192 unsigned validMarker1; |
| 0 | 193 |
| 194 } yaffs_ExtendedTags; | |
| 195 | |
| 196 #ifndef CONFIG_YAFFS_NO_YAFFS1 | |
| 197 // Spare structure | |
| 198 typedef struct | |
| 199 { | |
| 200 __u8 tagByte0; | |
| 201 __u8 tagByte1; | |
| 202 __u8 tagByte2; | |
| 203 __u8 tagByte3; | |
| 204 __u8 pageStatus; // set to 0 to delete the chunk | |
| 205 __u8 blockStatus; | |
| 206 __u8 tagByte4; | |
| 207 __u8 tagByte5; | |
| 208 __u8 ecc1[3]; | |
| 209 __u8 tagByte6; | |
| 210 __u8 tagByte7; | |
| 211 __u8 ecc2[3]; | |
| 212 } yaffs_Spare; | |
| 213 | |
| 214 //Special structure for passing through to mtd | |
| 215 struct yaffs_NANDSpare { | |
| 216 yaffs_Spare spare; | |
| 217 int eccres1; | |
| 218 int eccres2; | |
| 219 }; | |
| 220 #endif | |
| 221 | |
| 222 | |
| 223 // Block data in RAM | |
| 224 | |
| 225 typedef enum { | |
| 226 YAFFS_BLOCK_STATE_UNKNOWN = 0, | |
| 4 | 227 |
| 0 | 228 YAFFS_BLOCK_STATE_SCANNING, |
| 229 YAFFS_BLOCK_STATE_NEEDS_SCANNING,// The block might have something on it (ie it is allocating or full, perhaps empty) | |
| 230 // but it needs to be scanned to determine its true state. | |
| 231 // This state is only valid during yaffs_Scan. | |
| 232 // NB We tolerate empty because the pre-scanner might be incapable of deciding | |
| 233 // However, if this state is returned on a YAFFS2 device, then we expect a sequence number | |
| 234 | |
| 235 YAFFS_BLOCK_STATE_EMPTY, // This block is empty | |
| 236 | |
| 237 YAFFS_BLOCK_STATE_ALLOCATING, // This block is partially allocated. | |
| 238 // This is the one currently being used for page | |
| 239 // allocation. Should never be more than one of these | |
| 240 | |
| 241 | |
| 242 YAFFS_BLOCK_STATE_FULL, // All the pages in this block have been allocated. | |
| 243 // At least one page holds valid data. | |
| 244 | |
| 245 YAFFS_BLOCK_STATE_DIRTY, // All pages have been allocated and deleted. | |
| 246 // Erase me, reuse me. | |
| 247 | |
| 248 YAFFS_BLOCK_STATE_COLLECTING, // This block is being garbage collected | |
| 249 | |
| 250 YAFFS_BLOCK_STATE_DEAD // This block has failed and is not in use | |
| 251 | |
| 252 } yaffs_BlockState; | |
| 253 | |
| 254 | |
| 255 | |
| 256 | |
| 257 typedef struct | |
| 258 { | |
| 259 | |
| 15 | 260 int softDeletions:12; // number of soft deleted pages |
| 261 int pagesInUse:12; // number of pages in use | |
| 262 yaffs_BlockState blockState:4; // One of the above block states | |
| 0 | 263 __u32 needsRetiring:1; // Data has failed on this block, need to get valid data off |
| 264 // and retire the block. | |
| 4 | 265 #ifdef CONFIG_YAFFS_YAFFS2 |
| 0 | 266 __u32 hasShrinkHeader:1;// This block has at least one object header that does a shrink |
| 267 __u32 sequenceNumber; // block sequence number for yaffs2 | |
| 268 #endif | |
| 269 | |
| 270 } yaffs_BlockInfo; | |
| 271 | |
| 272 | |
| 273 //////////////////// Object structure /////////////////////////// | |
| 274 // This is the object structure as stored on NAND | |
| 275 | |
| 276 typedef struct | |
| 277 { | |
| 278 yaffs_ObjectType type; | |
| 279 | |
| 280 // Apply to everything | |
| 281 int parentObjectId; | |
| 282 __u16 sum__NoLongerUsed; // checksum of name. Calc this off the name to prevent inconsistencies | |
| 283 YCHAR name[YAFFS_MAX_NAME_LENGTH + 1]; | |
| 284 | |
| 285 // Thes following apply to directories, files, symlinks - not hard links | |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
286 __u32 yst_mode; // protection |
| 0 | 287 |
| 288 #ifdef CONFIG_YAFFS_WINCE | |
| 289 __u32 notForWinCE[5]; | |
| 290 #else | |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
291 __u32 yst_uid; // user ID of owner |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
292 __u32 yst_gid; // group ID of owner |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
293 __u32 yst_atime; // time of last access |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
294 __u32 yst_mtime; // time of last modification |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
295 __u32 yst_ctime; // time of last change |
| 0 | 296 #endif |
| 297 | |
| 298 // File size applies to files only | |
| 299 int fileSize; | |
| 300 | |
| 301 // Equivalent object id applies to hard links only. | |
| 302 int equivalentObjectId; | |
| 303 | |
| 304 // Alias is for symlinks only. | |
| 305 YCHAR alias[YAFFS_MAX_ALIAS_LENGTH + 1]; | |
| 306 | |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
307 __u32 yst_rdev; // device stuff for block and char devices (maj/min) |
| 0 | 308 |
| 309 #ifdef CONFIG_YAFFS_WINCE | |
| 310 __u32 win_ctime[2]; | |
| 311 __u32 win_atime[2]; | |
| 312 __u32 win_mtime[2]; | |
| 313 __u32 roomToGrow[5]; | |
| 314 #else | |
| 315 __u32 roomToGrow[11]; | |
| 316 #endif | |
| 317 | |
| 318 // isShrink applies to bject headers written when we shrink the file (ie resize) | |
| 319 __u32 isShrink; | |
| 320 | |
| 321 } yaffs_ObjectHeader; | |
| 322 | |
| 323 | |
| 324 | |
| 325 //////////////////// Tnode /////////////////////////// | |
| 326 | |
| 327 union yaffs_Tnode_union | |
| 328 { | |
| 329 #ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG | |
| 330 union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL+1]; | |
| 331 #else | |
| 332 union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL]; | |
| 333 #endif | |
| 334 __u16 level0[YAFFS_NTNODES_LEVEL0]; | |
| 335 | |
| 336 }; | |
| 337 | |
| 338 typedef union yaffs_Tnode_union yaffs_Tnode; | |
| 339 | |
| 340 struct yaffs_TnodeList_struct | |
| 341 { | |
| 342 struct yaffs_TnodeList_struct *next; | |
| 343 yaffs_Tnode *tnodes; | |
| 344 }; | |
| 345 | |
| 346 typedef struct yaffs_TnodeList_struct yaffs_TnodeList; | |
| 347 | |
| 348 | |
| 349 | |
| 350 /////////////////// Object //////////////////////////////// | |
| 351 // An object can be one of: | |
| 352 // - a directory (no data, has children links | |
| 353 // - a regular file (data.... not prunes :->). | |
| 354 // - a symlink [symbolic link] (the alias). | |
| 355 // - a hard link | |
| 356 | |
| 357 | |
| 358 typedef struct | |
| 359 { | |
| 360 __u32 fileSize; | |
| 361 __u32 scannedFileSize; | |
| 15 | 362 __u32 shrinkSize; |
| 0 | 363 int topLevel; |
| 364 yaffs_Tnode *top; | |
| 365 } yaffs_FileStructure; | |
| 366 | |
| 367 typedef struct | |
| 368 { | |
| 369 struct list_head children; // list of child links | |
| 370 } yaffs_DirectoryStructure; | |
| 371 | |
| 372 typedef struct | |
| 373 { | |
| 374 YCHAR *alias; | |
| 375 } yaffs_SymLinkStructure; | |
| 376 | |
| 377 typedef struct | |
| 378 { | |
| 379 struct yaffs_ObjectStruct *equivalentObject; | |
| 380 __u32 equivalentObjectId; | |
| 381 } yaffs_HardLinkStructure; | |
| 382 | |
| 383 typedef union | |
| 384 { | |
| 385 yaffs_FileStructure fileVariant; | |
| 386 yaffs_DirectoryStructure directoryVariant; | |
| 387 yaffs_SymLinkStructure symLinkVariant; | |
| 388 yaffs_HardLinkStructure hardLinkVariant; | |
| 389 } yaffs_ObjectVariant; | |
| 390 | |
| 391 | |
| 392 struct yaffs_ObjectStruct | |
| 393 { | |
| 394 __u8 deleted: 1; // This should only apply to unlinked files. | |
| 395 __u8 softDeleted: 1; // it has also been soft deleted | |
| 396 __u8 unlinked: 1; // An unlinked file. The file should be in the unlinked pseudo directory. | |
| 397 __u8 fake:1; // A fake object has no presence on NAND. | |
| 15 | 398 __u8 renameAllowed:1; // Some objects are not allowed to be renamed. |
| 0 | 399 __u8 unlinkAllowed:1; |
| 400 __u8 dirty:1; // the object needs to be written to flash | |
| 401 __u8 valid:1; // When the file system is being loaded up, this | |
| 402 // object might be created before the data | |
| 403 // is available (ie. file data records appear before the header). | |
| 404 __u8 serial; // serial number of chunk in NAND. Store here so we don't have to | |
| 4 | 405 |
| 406 __u8 deferedFree: 1; // For Linux kernel. Object is removed from NAND, but still in the inode cache. | |
| 407 // Free of object is defered. | |
| 15 | 408 |
| 409 __u8 lazyLoaded; // Vital info has been loaded from tags. Not all info available. | |
| 410 // | |
| 4 | 411 |
| 15 | 412 // read back the old one to update. |
| 413 __u16 sum; // sum of the name to speed searching | |
| 0 | 414 |
| 415 struct yaffs_DeviceStruct *myDev; // The device I'm on | |
| 416 | |
| 417 | |
| 418 struct list_head hashLink; // list of objects in this hash bucket | |
| 419 | |
| 420 | |
| 421 struct list_head hardLinks; // all the equivalent hard linked objects | |
| 422 // live on this list | |
| 423 // directory structure stuff | |
| 424 struct yaffs_ObjectStruct *parent; //my parent directory | |
| 425 struct list_head siblings; // siblings in a directory | |
| 426 // also used for linking up the free list | |
| 427 | |
| 20 | 428 // Where's my object header in NAND? |
| 0 | 429 int chunkId; // where it lives |
| 430 | |
| 20 | 431 int nDataChunks; // Number of data chunks attached to the file. |
| 0 | 432 |
| 433 __u32 objectId; // the object id value | |
| 434 | |
| 435 | |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
436 __u32 yst_mode; // protection |
| 0 | 437 |
| 438 #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM | |
| 439 YCHAR shortName[YAFFS_SHORT_NAME_LENGTH+1]; | |
| 440 #endif | |
| 441 | |
| 442 #ifndef __KERNEL__ | |
| 443 __u32 inUse; | |
| 444 #endif | |
| 445 | |
| 446 #ifdef CONFIG_YAFFS_WINCE | |
| 447 __u32 win_ctime[2]; | |
| 448 __u32 win_mtime[2]; | |
| 449 __u32 win_atime[2]; | |
| 450 #else | |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
451 __u32 yst_uid; // user ID of owner |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
452 __u32 yst_gid; // group ID of owner |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
453 __u32 yst_atime; // time of last access |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
454 __u32 yst_mtime; // time of last modification |
|
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
455 __u32 yst_ctime; // time of last change |
| 0 | 456 #endif |
| 457 | |
|
24
4ebabd859f38
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles
parents:
22
diff
changeset
|
458 __u32 yst_rdev; // device stuff for block and char devices |
| 0 | 459 |
| 460 | |
| 461 | |
| 462 #ifdef __KERNEL__ | |
| 463 struct inode *myInode; | |
| 4 | 464 |
| 0 | 465 #endif |
| 466 | |
| 467 | |
| 468 | |
| 469 yaffs_ObjectType variantType; | |
| 470 | |
| 471 yaffs_ObjectVariant variant; | |
| 472 | |
| 473 }; | |
| 474 | |
| 475 | |
| 476 | |
| 477 typedef struct yaffs_ObjectStruct yaffs_Object; | |
| 478 | |
| 479 | |
| 480 struct yaffs_ObjectList_struct | |
| 481 { | |
| 482 yaffs_Object *objects; | |
| 483 struct yaffs_ObjectList_struct *next; | |
| 484 }; | |
| 485 | |
| 486 typedef struct yaffs_ObjectList_struct yaffs_ObjectList; | |
| 487 | |
| 488 typedef struct | |
| 489 { | |
| 490 struct list_head list; | |
| 491 int count; | |
| 492 } yaffs_ObjectBucket; | |
| 493 | |
| 494 ///////////////////// Temporary buffers //////////////////// | |
| 495 // | |
| 496 // These are chunk-sized working buffers. Each device has a few | |
| 497 | |
| 498 typedef struct { | |
| 499 __u8 *buffer; | |
| 500 int line; // track from whence this buffer was allocated | |
| 501 int maxLine; | |
| 502 } yaffs_TempBuffer; | |
| 503 | |
| 504 //////////////////// Device //////////////////////////////// | |
| 505 | |
| 506 struct yaffs_DeviceStruct | |
| 507 { | |
| 508 // Entry parameters set up way early. Yaffs sets up the rest. | |
| 509 int nBytesPerChunk; // Should be a power of 2 >= 512 | |
| 510 int nChunksPerBlock; // does not need to be a power of 2 | |
| 511 int nBytesPerSpare; // spare area size | |
| 512 int startBlock; // Start block we're allowed to use | |
| 513 int endBlock; // End block we're allowed to use | |
| 514 int nReservedBlocks; // We want this tuneable so that we can reduce | |
| 515 // reserved blocks on NOR and RAM. | |
| 516 | |
| 517 int nShortOpCaches; // If <= 0, then short op caching is disabled, else | |
| 518 // the number of short op caches (don't use too many). | |
| 519 | |
| 520 int useHeaderFileSize; // Flag to determine if we should use file sizes from the header | |
| 521 | |
| 522 int useNANDECC; // Flag to decide whether or not to use NANDECC | |
| 523 | |
| 524 | |
| 525 void *genericDevice; // Pointer to device context | |
| 526 // On an mtd this holds the mtd pointer. | |
| 527 | |
| 528 // NAND access functions (Must be set before calling YAFFS) | |
| 529 | |
| 4 | 530 |
| 0 | 531 int (*writeChunkToNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, const yaffs_Spare *spare); |
| 532 int (*readChunkFromNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare); | |
| 4 | 533 int (*eraseBlockInNAND)(struct yaffs_DeviceStruct *dev,int blockInNAND); |
| 534 int (*initialiseNAND)(struct yaffs_DeviceStruct *dev); | |
| 535 | |
| 536 #ifdef CONFIG_YAFFS_YAFFS2 | |
| 0 | 537 int (*writeChunkWithTagsToNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_ExtendedTags *tags); |
| 538 int (*readChunkWithTagsFromNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags); | |
| 539 int (*markNANDBlockBad)(struct yaffs_DeviceStruct *dev, int blockNo); | |
| 540 int (*queryNANDBlock)(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber); | |
| 541 #endif | |
| 542 | |
| 543 int isYaffs2; | |
| 544 | |
| 545 // End of stuff that must be set before initialisation. | |
| 546 | |
| 547 // Runtime parameters. Set up by YAFFS. | |
| 548 | |
| 549 __u16 chunkGroupBits; // 0 for devices <= 32MB. else log2(nchunks) - 16 | |
| 550 __u16 chunkGroupSize; // == 2^^chunkGroupBits | |
| 551 | |
| 552 #ifdef __KERNEL__ | |
| 553 | |
| 554 struct semaphore sem;// Semaphore for waiting on erasure. | |
| 555 struct semaphore grossLock; // Gross locking semaphore | |
| 7 | 556 __u8 * spareBuffer; // For mtdif2 use. Don't know the size of the buffer at compile time so we have to allocate it. |
| 0 | 557 void (*putSuperFunc)(struct super_block *sb); |
| 558 #endif | |
| 559 | |
| 560 int isMounted; | |
| 561 | |
| 21 | 562 // Stuff to support block offsetting to support start block zero |
| 563 int internalStartBlock; | |
| 564 int internalEndBlock; | |
| 565 int blockOffset; | |
| 566 int chunkOffset; | |
| 567 | |
| 0 | 568 // Block Info |
| 569 yaffs_BlockInfo *blockInfo; | |
| 570 __u8 *chunkBits; // bitmap of chunks in use | |
| 571 int chunkBitmapStride; // Number of bytes of chunkBits per block. | |
| 572 // Must be consistent with nChunksPerBlock. | |
| 573 | |
| 574 | |
| 575 int nErasedBlocks; | |
| 576 int allocationBlock; // Current block being allocated off | |
| 577 __u32 allocationPage; | |
| 578 int allocationBlockFinder; // Used to search for next allocation block | |
| 579 | |
| 580 // Runtime state | |
| 581 int nTnodesCreated; | |
| 582 yaffs_Tnode *freeTnodes; | |
| 583 int nFreeTnodes; | |
| 584 yaffs_TnodeList *allocatedTnodeList; | |
| 585 | |
| 27 | 586 int isDoingGC; |
| 0 | 587 |
| 588 int nObjectsCreated; | |
| 589 yaffs_Object *freeObjects; | |
| 590 int nFreeObjects; | |
| 591 | |
| 592 yaffs_ObjectList *allocatedObjectList; | |
| 593 | |
| 594 yaffs_ObjectBucket objectBucket[YAFFS_NOBJECT_BUCKETS]; | |
| 595 | |
| 596 int nFreeChunks; | |
| 597 | |
| 598 int currentDirtyChecker; // Used to find current dirtiest block | |
| 599 | |
| 600 __u32 *gcCleanupList; // objects to delete at the end of a GC. | |
| 601 | |
| 602 // Operations since mount | |
| 603 int nPageWrites; | |
| 604 int nPageReads; | |
| 605 int nBlockErasures; | |
| 606 int nErasureFailures; | |
| 607 int nGCCopies; | |
| 608 int garbageCollections; | |
| 609 int passiveGarbageCollections; | |
| 610 int nRetriedWrites; | |
| 611 int nRetiredBlocks; | |
| 612 int eccFixed; | |
| 613 int eccUnfixed; | |
| 614 int tagsEccFixed; | |
| 615 int tagsEccUnfixed; | |
| 616 int nDeletions; | |
| 617 int nUnmarkedDeletions; | |
| 618 | |
| 619 yaffs_Object *rootDir; | |
| 620 yaffs_Object *lostNFoundDir; | |
| 621 | |
| 622 // Buffer areas for storing data to recover from write failures | |
| 623 // __u8 bufferedData[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK]; | |
| 624 // yaffs_Spare bufferedSpare[YAFFS_CHUNKS_PER_BLOCK]; | |
| 625 int bufferedBlock; // Which block is buffered here? | |
| 626 int doingBufferedBlockRewrite; | |
| 627 | |
| 628 yaffs_ChunkCache *srCache; | |
| 629 int srLastUse; | |
| 630 | |
| 631 int cacheHits; | |
| 632 | |
| 633 // Stuff for background deletion and unlinked files. | |
| 634 yaffs_Object *unlinkedDir; // Directory where unlinked and deleted files live. | |
| 635 yaffs_Object *deletedDir; // Directory where deleted objects are sent to disappear. | |
| 636 yaffs_Object *unlinkedDeletion; // Current file being background deleted. | |
| 637 int nDeletedFiles; // Count of files awaiting deletion; | |
| 638 int nUnlinkedFiles; // Count of unlinked files. | |
| 639 int nBackgroundDeletions; // Count of background deletions. | |
| 640 | |
| 641 //__u8 *localBuffer; | |
| 642 | |
| 643 yaffs_TempBuffer tempBuffer[YAFFS_N_TEMP_BUFFERS]; | |
| 644 int maxTemp; | |
| 645 int unmanagedTempAllocations; | |
| 646 int unmanagedTempDeallocations; | |
| 647 | |
| 648 // yaffs2 runtime stuff | |
| 649 unsigned sequenceNumber; //Sequence number of currently allocating block | |
| 650 unsigned oldestDirtySequence; | |
| 651 | |
| 652 }; | |
| 653 | |
| 654 typedef struct yaffs_DeviceStruct yaffs_Device; | |
| 655 | |
| 656 | |
| 657 // Function to manipulate block info | |
| 658 static Y_INLINE yaffs_BlockInfo* yaffs_GetBlockInfo(yaffs_Device *dev, int blk) | |
| 659 { | |
| 22 | 660 if(blk < dev->internalStartBlock || blk > dev->internalEndBlock) |
| 0 | 661 { |
| 662 T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),blk)); | |
| 663 YBUG(); | |
| 664 } | |
| 22 | 665 return &dev->blockInfo[blk - dev->internalStartBlock]; |
| 0 | 666 } |
| 667 | |
| 668 | |
| 669 //////////// YAFFS Functions ////////////////// | |
| 670 | |
| 671 int yaffs_GutsInitialise(yaffs_Device *dev); | |
| 672 void yaffs_Deinitialise(yaffs_Device *dev); | |
| 673 | |
| 674 int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev); | |
| 675 | |
| 676 | |
| 677 // Rename | |
| 678 int yaffs_RenameObject(yaffs_Object *oldDir, const YCHAR *oldName, yaffs_Object *newDir, const YCHAR *newName); | |
| 679 | |
| 680 // generic Object functions | |
| 681 int yaffs_Unlink(yaffs_Object *dir, const YCHAR *name); | |
| 682 int yaffs_DeleteFile(yaffs_Object *obj); | |
| 683 | |
| 684 // Object access functions. | |
| 685 int yaffs_GetObjectName(yaffs_Object *obj,YCHAR *name,int buffSize); | |
| 686 int yaffs_GetObjectFileLength(yaffs_Object *obj); | |
| 687 int yaffs_GetObjectInode(yaffs_Object *obj); | |
| 688 unsigned yaffs_GetObjectType(yaffs_Object *obj); | |
| 689 int yaffs_GetObjectLinkCount(yaffs_Object *obj); | |
| 690 | |
| 691 // Change inode attributes | |
| 692 int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr); | |
| 693 int yaffs_GetAttributes(yaffs_Object *obj, struct iattr *attr); | |
| 694 | |
| 695 // File operations | |
| 696 int yaffs_ReadDataFromFile(yaffs_Object *obj, __u8 *buffer, __u32 offset, int nBytes); | |
| 20 | 697 int yaffs_WriteDataToFile(yaffs_Object *obj, const __u8 *buffer, __u32 offset, int nBytes, int writeThrough); |
| 0 | 698 int yaffs_ResizeFile(yaffs_Object *obj, int newSize); |
| 699 | |
| 700 yaffs_Object *yaffs_MknodFile(yaffs_Object *parent,const YCHAR *name, __u32 mode, __u32 uid, __u32 gid); | |
| 701 int yaffs_FlushFile(yaffs_Object *obj,int updateTime); | |
| 702 | |
| 703 | |
| 704 // Directory operations | |
| 705 yaffs_Object *yaffs_MknodDirectory(yaffs_Object *parent,const YCHAR *name, __u32 mode, __u32 uid, __u32 gid); | |
| 706 yaffs_Object *yaffs_FindObjectByName(yaffs_Object *theDir,const YCHAR *name); | |
| 707 int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,int (*fn)(yaffs_Object *)); | |
| 708 | |
| 709 yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev,__u32 number); | |
| 710 | |
| 711 // Link operations | |
| 712 yaffs_Object *yaffs_Link(yaffs_Object *parent, const YCHAR *name, yaffs_Object *equivalentObject); | |
| 713 | |
| 714 yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj); | |
| 715 | |
| 716 // Symlink operations | |
| 717 yaffs_Object *yaffs_MknodSymLink(yaffs_Object *parent, const YCHAR *name, __u32 mode, __u32 uid, __u32 gid, const YCHAR *alias); | |
| 718 YCHAR *yaffs_GetSymlinkAlias(yaffs_Object *obj); | |
| 719 | |
| 720 // Special inodes (fifos, sockets and devices) | |
| 721 yaffs_Object *yaffs_MknodSpecial(yaffs_Object *parent,const YCHAR *name, __u32 mode, __u32 uid, __u32 gid,__u32 rdev); | |
| 722 | |
| 723 | |
| 724 // Special directories | |
| 725 yaffs_Object *yaffs_Root(yaffs_Device *dev); | |
| 726 yaffs_Object *yaffs_LostNFound(yaffs_Device *dev); | |
| 727 | |
| 728 #ifdef CONFIG_YAFFS_WINCE | |
| 729 // CONFIG_YAFFS_WINCE special stuff | |
| 730 void yfsd_WinFileTimeNow(__u32 target[2]); | |
| 731 #endif | |
| 732 | |
| 4 | 733 #ifdef __KERNEL__ |
| 734 | |
| 735 void yaffs_HandleDeferedFree(yaffs_Object *obj); | |
| 736 #endif | |
| 737 | |
| 738 | |
| 739 | |
| 0 | 740 |
| 741 // Debug dump | |
| 742 int yaffs_DumpObject(yaffs_Object *obj); | |
| 743 | |
| 744 | |
| 745 void yaffs_GutsTest(yaffs_Device *dev); | |
| 746 | |
| 747 | |
| 748 void yaffs_InitialiseTags(yaffs_ExtendedTags *tags); | |
| 749 void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId,int markNAND,int lyn); | |
| 750 int yaffs_CheckFF(__u8 *buffer,int nBytes); | |
| 751 | |
| 752 #endif | |
| 753 |
