Home | History | Annotate | Download | only in yaffs2
      1 /*
      2  * YAFFS: Yet another FFS. A NAND-flash specific file system.
      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 (at) 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: yaffs_guts.h,v 1.25 2006/10/13 08:52:49 charles Exp $
     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  */
     35 #define YAFFS_MAGIC			0x5941FF53
     36 
     37 #define YAFFS_NTNODES_LEVEL0	  	16
     38 #define YAFFS_TNODES_LEVEL0_BITS	4
     39 #define YAFFS_TNODES_LEVEL0_MASK	0xf
     40 
     41 #define YAFFS_NTNODES_INTERNAL 		(YAFFS_NTNODES_LEVEL0 / 2)
     42 #define YAFFS_TNODES_INTERNAL_BITS 	(YAFFS_TNODES_LEVEL0_BITS - 1)
     43 #define YAFFS_TNODES_INTERNAL_MASK	0x7
     44 #define YAFFS_TNODES_MAX_LEVEL		6
     45 
     46 #ifndef CONFIG_YAFFS_NO_YAFFS1
     47 #define YAFFS_BYTES_PER_SPARE		16
     48 #define YAFFS_BYTES_PER_CHUNK		512
     49 #define YAFFS_CHUNK_SIZE_SHIFT		9
     50 #define YAFFS_CHUNKS_PER_BLOCK		32
     51 #define YAFFS_BYTES_PER_BLOCK		(YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK)
     52 #endif
     53 
     54 #define YAFFS_MIN_YAFFS2_CHUNK_SIZE 	1024
     55 #define YAFFS_MIN_YAFFS2_SPARE_SIZE	32
     56 
     57 #define YAFFS_MAX_CHUNK_ID		0x000FFFFF
     58 
     59 #define YAFFS_UNUSED_OBJECT_ID		0x0003FFFF
     60 
     61 #define YAFFS_ALLOCATION_NOBJECTS	100
     62 #define YAFFS_ALLOCATION_NTNODES	100
     63 #define YAFFS_ALLOCATION_NLINKS		100
     64 
     65 #define YAFFS_NOBJECT_BUCKETS		256
     66 
     67 
     68 #define YAFFS_OBJECT_SPACE		0x40000
     69 
     70 #define YAFFS_NCHECKPOINT_OBJECTS	5000
     71 
     72 #define YAFFS_CHECKPOINT_VERSION 	2
     73 
     74 #ifdef CONFIG_YAFFS_UNICODE
     75 #define YAFFS_MAX_NAME_LENGTH		127
     76 #define YAFFS_MAX_ALIAS_LENGTH		79
     77 #else
     78 #define YAFFS_MAX_NAME_LENGTH		255
     79 #define YAFFS_MAX_ALIAS_LENGTH		159
     80 #endif
     81 
     82 #define YAFFS_SHORT_NAME_LENGTH		15
     83 
     84 /* Some special object ids for pseudo objects */
     85 #define YAFFS_OBJECTID_ROOT		1
     86 #define YAFFS_OBJECTID_LOSTNFOUND	2
     87 #define YAFFS_OBJECTID_UNLINKED		3
     88 #define YAFFS_OBJECTID_DELETED		4
     89 
     90 /* Sseudo object ids for checkpointing */
     91 #define YAFFS_OBJECTID_SB_HEADER	0x10
     92 #define YAFFS_OBJECTID_CHECKPOINT_DATA	0x20
     93 #define YAFFS_SEQUENCE_CHECKPOINT_DATA  0x21
     94 
     95 /* */
     96 
     97 #define YAFFS_MAX_SHORT_OP_CACHES	20
     98 
     99 #define YAFFS_N_TEMP_BUFFERS		4
    100 
    101 /* Sequence numbers are used in YAFFS2 to determine block allocation order.
    102  * The range is limited slightly to help distinguish bad numbers from good.
    103  * This also allows us to perhaps in the future use special numbers for
    104  * special purposes.
    105  * EFFFFF00 allows the allocation of 8 blocks per second (~1Mbytes) for 15 years,
    106  * and is a larger number than the lifetime of a 2GB device.
    107  */
    108 #define YAFFS_LOWEST_SEQUENCE_NUMBER	0x00001000
    109 #define YAFFS_HIGHEST_SEQUENCE_NUMBER	0xEFFFFF00
    110 
    111 /* ChunkCache is used for short read/write operations.*/
    112 typedef struct {
    113 	struct yaffs_ObjectStruct *object;
    114 	int chunkId;
    115 	int lastUse;
    116 	int dirty;
    117 	int nBytes;		/* Only valid if the cache is dirty */
    118 	int locked;		/* Can't push out or flush while locked. */
    119 #ifdef CONFIG_YAFFS_YAFFS2
    120 	__u8 *data;
    121 #else
    122 	__u8 data[YAFFS_BYTES_PER_CHUNK];
    123 #endif
    124 } yaffs_ChunkCache;
    125 
    126 
    127 
    128 /* Tags structures in RAM
    129  * NB This uses bitfield. Bitfields should not straddle a u32 boundary otherwise
    130  * the structure size will get blown out.
    131  */
    132 
    133 #ifndef CONFIG_YAFFS_NO_YAFFS1
    134 typedef struct {
    135 	unsigned chunkId:20;
    136 	unsigned serialNumber:2;
    137 	unsigned byteCount:10;
    138 	unsigned objectId:18;
    139 	unsigned ecc:12;
    140 	unsigned unusedStuff:2;
    141 
    142 } yaffs_Tags;
    143 
    144 typedef union {
    145 	yaffs_Tags asTags;
    146 	__u8 asBytes[8];
    147 } yaffs_TagsUnion;
    148 
    149 #endif
    150 
    151 /* Stuff used for extended tags in YAFFS2 */
    152 
    153 typedef enum {
    154 	YAFFS_ECC_RESULT_UNKNOWN,
    155 	YAFFS_ECC_RESULT_NO_ERROR,
    156 	YAFFS_ECC_RESULT_FIXED,
    157 	YAFFS_ECC_RESULT_UNFIXED
    158 } yaffs_ECCResult;
    159 
    160 typedef enum {
    161 	YAFFS_OBJECT_TYPE_UNKNOWN,
    162 	YAFFS_OBJECT_TYPE_FILE,
    163 	YAFFS_OBJECT_TYPE_SYMLINK,
    164 	YAFFS_OBJECT_TYPE_DIRECTORY,
    165 	YAFFS_OBJECT_TYPE_HARDLINK,
    166 	YAFFS_OBJECT_TYPE_SPECIAL
    167 } yaffs_ObjectType;
    168 
    169 typedef struct {
    170 
    171 	unsigned validMarker0;
    172 	unsigned chunkUsed;	/*  Status of the chunk: used or unused */
    173 	unsigned objectId;	/* If 0 then this is not part of an object (unused) */
    174 	unsigned chunkId;	/* If 0 then this is a header, else a data chunk */
    175 	unsigned byteCount;	/* Only valid for data chunks */
    176 
    177 	/* The following stuff only has meaning when we read */
    178 	yaffs_ECCResult eccResult;
    179 	unsigned blockBad;
    180 
    181 	/* YAFFS 1 stuff */
    182 	unsigned chunkDeleted;	/* The chunk is marked deleted */
    183 	unsigned serialNumber;	/* Yaffs1 2-bit serial number */
    184 
    185 	/* YAFFS2 stuff */
    186 	unsigned sequenceNumber;	/* The sequence number of this block */
    187 
    188 	/* Extra info if this is an object header (YAFFS2 only) */
    189 
    190 	unsigned extraHeaderInfoAvailable;	/* There is extra info available if this is not zero */
    191 	unsigned extraParentObjectId;	/* The parent object */
    192 	unsigned extraIsShrinkHeader;	/* Is it a shrink header? */
    193 	unsigned extraShadows;		/* Does this shadow another object? */
    194 
    195 	yaffs_ObjectType extraObjectType;	/* What object type? */
    196 
    197 	unsigned extraFileLength;		/* Length if it is a file */
    198 	unsigned extraEquivalentObjectId;	/* Equivalent object Id if it is a hard link */
    199 
    200 	unsigned validMarker1;
    201 
    202 } yaffs_ExtendedTags;
    203 
    204 /* Spare structure for YAFFS1 */
    205 typedef struct {
    206 	__u8 tagByte0;
    207 	__u8 tagByte1;
    208 	__u8 tagByte2;
    209 	__u8 tagByte3;
    210 	__u8 pageStatus;	/* set to 0 to delete the chunk */
    211 	__u8 blockStatus;
    212 	__u8 tagByte4;
    213 	__u8 tagByte5;
    214 	__u8 ecc1[3];
    215 	__u8 tagByte6;
    216 	__u8 tagByte7;
    217 	__u8 ecc2[3];
    218 } yaffs_Spare;
    219 
    220 /*Special structure for passing through to mtd */
    221 struct yaffs_NANDSpare {
    222 	yaffs_Spare spare;
    223 	int eccres1;
    224 	int eccres2;
    225 };
    226 
    227 /* Block data in RAM */
    228 
    229 typedef enum {
    230 	YAFFS_BLOCK_STATE_UNKNOWN = 0,
    231 
    232 	YAFFS_BLOCK_STATE_SCANNING,
    233 	YAFFS_BLOCK_STATE_NEEDS_SCANNING,
    234 	/* The block might have something on it (ie it is allocating or full, perhaps empty)
    235 	 * but it needs to be scanned to determine its true state.
    236 	 * This state is only valid during yaffs_Scan.
    237 	 * NB We tolerate empty because the pre-scanner might be incapable of deciding
    238 	 * However, if this state is returned on a YAFFS2 device, then we expect a sequence number
    239 	 */
    240 
    241 	YAFFS_BLOCK_STATE_EMPTY,
    242 	/* This block is empty */
    243 
    244 	YAFFS_BLOCK_STATE_ALLOCATING,
    245 	/* This block is partially allocated.
    246 	 * At least one page holds valid data.
    247 	 * This is the one currently being used for page
    248 	 * allocation. Should never be more than one of these
    249 	 */
    250 
    251 	YAFFS_BLOCK_STATE_FULL,
    252 	/* All the pages in this block have been allocated.
    253 	 */
    254 
    255 	YAFFS_BLOCK_STATE_DIRTY,
    256 	/* All pages have been allocated and deleted.
    257 	 * Erase me, reuse me.
    258 	 */
    259 
    260 	YAFFS_BLOCK_STATE_CHECKPOINT,
    261 	/* This block is assigned to holding checkpoint data.
    262 	 */
    263 
    264 	YAFFS_BLOCK_STATE_COLLECTING,
    265 	/* This block is being garbage collected */
    266 
    267 	YAFFS_BLOCK_STATE_DEAD
    268 	/* This block has failed and is not in use */
    269 } yaffs_BlockState;
    270 
    271 typedef struct {
    272 
    273 	int softDeletions:10;	/* number of soft deleted pages */
    274 	int pagesInUse:10;	/* number of pages in use */
    275 	yaffs_BlockState blockState:4;	/* One of the above block states */
    276 	__u32 needsRetiring:1;	/* Data has failed on this block, need to get valid data off */
    277                         	/* and retire the block. */
    278 	__u32 skipErasedCheck: 1; /* If this is set we can skip the erased check on this block */
    279 	__u32 gcPrioritise: 1; 	/* An ECC check or bank check has failed on this block.
    280 				   It should be prioritised for GC */
    281         __u32 chunkErrorStrikes:3; /* How many times we've had ecc etc failures on this block and tried to reuse it */
    282 
    283 #ifdef CONFIG_YAFFS_YAFFS2
    284 	__u32 hasShrinkHeader:1; /* This block has at least one shrink object header */
    285 	__u32 sequenceNumber;	 /* block sequence number for yaffs2 */
    286 #endif
    287 
    288 } yaffs_BlockInfo;
    289 
    290 /* -------------------------- Object structure -------------------------------*/
    291 /* This is the object structure as stored on NAND */
    292 
    293 typedef struct {
    294 	yaffs_ObjectType type;
    295 
    296 	/* Apply to everything  */
    297 	int parentObjectId;
    298 	__u16 sum__NoLongerUsed;	/* checksum of name. No longer used */
    299 	YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
    300 
    301 	/* Thes following apply to directories, files, symlinks - not hard links */
    302 	__u32 yst_mode;		/* protection */
    303 
    304 #ifdef CONFIG_YAFFS_WINCE
    305 	__u32 notForWinCE[5];
    306 #else
    307 	__u32 yst_uid;
    308 	__u32 yst_gid;
    309 	__u32 yst_atime;
    310 	__u32 yst_mtime;
    311 	__u32 yst_ctime;
    312 #endif
    313 
    314 	/* File size  applies to files only */
    315 	int fileSize;
    316 
    317 	/* Equivalent object id applies to hard links only. */
    318 	int equivalentObjectId;
    319 
    320 	/* Alias is for symlinks only. */
    321 	YCHAR alias[YAFFS_MAX_ALIAS_LENGTH + 1];
    322 
    323 	__u32 yst_rdev;		/* device stuff for block and char devices (major/min) */
    324 
    325 #ifdef CONFIG_YAFFS_WINCE
    326 	__u32 win_ctime[2];
    327 	__u32 win_atime[2];
    328 	__u32 win_mtime[2];
    329 	__u32 roomToGrow[4];
    330 #else
    331 	__u32 roomToGrow[10];
    332 #endif
    333 
    334 	int shadowsObject;	/* This object header shadows the specified object if > 0 */
    335 
    336 	/* isShrink applies to object headers written when we shrink the file (ie resize) */
    337 	__u32 isShrink;
    338 
    339 } yaffs_ObjectHeader;
    340 
    341 /*--------------------------- Tnode -------------------------- */
    342 
    343 union yaffs_Tnode_union {
    344 #ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
    345 	union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL + 1];
    346 #else
    347 	union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL];
    348 #endif
    349 /*	__u16 level0[YAFFS_NTNODES_LEVEL0]; */
    350 
    351 };
    352 
    353 typedef union yaffs_Tnode_union yaffs_Tnode;
    354 
    355 struct yaffs_TnodeList_struct {
    356 	struct yaffs_TnodeList_struct *next;
    357 	yaffs_Tnode *tnodes;
    358 };
    359 
    360 typedef struct yaffs_TnodeList_struct yaffs_TnodeList;
    361 
    362 /*------------------------  Object -----------------------------*/
    363 /* An object can be one of:
    364  * - a directory (no data, has children links
    365  * - a regular file (data.... not prunes :->).
    366  * - a symlink [symbolic link] (the alias).
    367  * - a hard link
    368  */
    369 
    370 typedef struct {
    371 	__u32 fileSize;
    372 	__u32 scannedFileSize;
    373 	__u32 shrinkSize;
    374 	int topLevel;
    375 	yaffs_Tnode *top;
    376 } yaffs_FileStructure;
    377 
    378 typedef struct {
    379 	struct list_head children;	/* list of child links */
    380 } yaffs_DirectoryStructure;
    381 
    382 typedef struct {
    383 	YCHAR *alias;
    384 } yaffs_SymLinkStructure;
    385 
    386 typedef struct {
    387 	struct yaffs_ObjectStruct *equivalentObject;
    388 	__u32 equivalentObjectId;
    389 } yaffs_HardLinkStructure;
    390 
    391 typedef union {
    392 	yaffs_FileStructure fileVariant;
    393 	yaffs_DirectoryStructure directoryVariant;
    394 	yaffs_SymLinkStructure symLinkVariant;
    395 	yaffs_HardLinkStructure hardLinkVariant;
    396 } yaffs_ObjectVariant;
    397 
    398 struct yaffs_ObjectStruct {
    399 	__u8 deleted:1;		/* This should only apply to unlinked files. */
    400 	__u8 softDeleted:1;	/* it has also been soft deleted */
    401 	__u8 unlinked:1;	/* An unlinked file. The file should be in the unlinked directory.*/
    402 	__u8 fake:1;		/* A fake object has no presence on NAND. */
    403 	__u8 renameAllowed:1;	/* Some objects are not allowed to be renamed. */
    404 	__u8 unlinkAllowed:1;
    405 	__u8 dirty:1;		/* the object needs to be written to flash */
    406 	__u8 valid:1;		/* When the file system is being loaded up, this
    407 				 * object might be created before the data
    408 				 * is available (ie. file data records appear before the header).
    409 				 */
    410 	__u8 lazyLoaded:1;	/* This object has been lazy loaded and is missing some detail */
    411 
    412 	__u8 deferedFree:1;	/* For Linux kernel. Object is removed from NAND, but is
    413 				 * still in the inode cache. Free of object is defered.
    414 				 * until the inode is released.
    415 				 */
    416 
    417 	__u8 serial;		/* serial number of chunk in NAND. Cached here */
    418 	__u16 sum;		/* sum of the name to speed searching */
    419 
    420 	struct yaffs_DeviceStruct *myDev;	/* The device I'm on */
    421 
    422 	struct list_head hashLink;	/* list of objects in this hash bucket */
    423 
    424 	struct list_head hardLinks;	/* all the equivalent hard linked objects */
    425 
    426 	/* directory structure stuff */
    427 	/* also used for linking up the free list */
    428 	struct yaffs_ObjectStruct *parent;
    429 	struct list_head siblings;
    430 
    431 	/* Where's my object header in NAND? */
    432 	int chunkId;
    433 
    434 	int nDataChunks;	/* Number of data chunks attached to the file. */
    435 
    436 	__u32 objectId;		/* the object id value */
    437 
    438 	__u32 yst_mode;
    439 
    440 #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
    441 	YCHAR shortName[YAFFS_SHORT_NAME_LENGTH + 1];
    442 #endif
    443 
    444 #ifndef __KERNEL__
    445 	__u32 inUse;
    446 #endif
    447 
    448 #ifdef CONFIG_YAFFS_WINCE
    449 	__u32 win_ctime[2];
    450 	__u32 win_mtime[2];
    451 	__u32 win_atime[2];
    452 #else
    453 	__u32 yst_uid;
    454 	__u32 yst_gid;
    455 	__u32 yst_atime;
    456 	__u32 yst_mtime;
    457 	__u32 yst_ctime;
    458 #endif
    459 
    460 	__u32 yst_rdev;
    461 
    462 #ifdef __KERNEL__
    463 	struct inode *myInode;
    464 
    465 #endif
    466 
    467 	yaffs_ObjectType variantType;
    468 
    469 	yaffs_ObjectVariant variant;
    470 
    471 };
    472 
    473 typedef struct yaffs_ObjectStruct yaffs_Object;
    474 
    475 struct yaffs_ObjectList_struct {
    476 	yaffs_Object *objects;
    477 	struct yaffs_ObjectList_struct *next;
    478 };
    479 
    480 typedef struct yaffs_ObjectList_struct yaffs_ObjectList;
    481 
    482 typedef struct {
    483 	struct list_head list;
    484 	int count;
    485 } yaffs_ObjectBucket;
    486 
    487 
    488 /* yaffs_CheckpointObject holds the definition of an object as dumped
    489  * by checkpointing.
    490  */
    491 
    492 typedef struct {
    493         int structType;
    494 	__u32 objectId;
    495 	__u32 parentId;
    496 	int chunkId;
    497 
    498 	yaffs_ObjectType variantType:3;
    499 	__u8 deleted:1;
    500 	__u8 softDeleted:1;
    501 	__u8 unlinked:1;
    502 	__u8 fake:1;
    503 	__u8 renameAllowed:1;
    504 	__u8 unlinkAllowed:1;
    505 	__u8 serial;
    506 
    507 	int nDataChunks;
    508 	__u32 fileSizeOrEquivalentObjectId;
    509 
    510 }yaffs_CheckpointObject;
    511 
    512 /*--------------------- Temporary buffers ----------------
    513  *
    514  * These are chunk-sized working buffers. Each device has a few
    515  */
    516 
    517 typedef struct {
    518 	__u8 *buffer;
    519 	int line;	/* track from whence this buffer was allocated */
    520 	int maxLine;
    521 } yaffs_TempBuffer;
    522 
    523 /*----------------- Device ---------------------------------*/
    524 
    525 struct yaffs_DeviceStruct {
    526 	struct list_head devList;
    527 	const char *name;
    528 
    529 	/* Entry parameters set up way early. Yaffs sets up the rest.*/
    530 	int nDataBytesPerChunk;	/* Should be a power of 2 >= 512 */
    531 	int nChunksPerBlock;	/* does not need to be a power of 2 */
    532 	int nBytesPerSpare;	/* spare area size */
    533 	int startBlock;		/* Start block we're allowed to use */
    534 	int endBlock;		/* End block we're allowed to use */
    535 	int nReservedBlocks;	/* We want this tuneable so that we can reduce */
    536 				/* reserved blocks on NOR and RAM. */
    537 
    538 	/* Stuff used by the partitioned checkpointing mechanism */
    539 	int checkpointStartBlock;
    540 	int checkpointEndBlock;
    541 
    542 	/* Stuff used by the shared space checkpointing mechanism */
    543 	/* If this value is zero, then this mechanism is disabled */
    544 
    545 	int nCheckpointReservedBlocks; /* Blocks to reserve for checkpoint data */
    546 
    547 
    548 
    549 
    550 	int nShortOpCaches;	/* If <= 0, then short op caching is disabled, else
    551 				 * the number of short op caches (don't use too many)
    552 				 */
    553 
    554 	int useHeaderFileSize;	/* Flag to determine if we should use file sizes from the header */
    555 
    556 	int useNANDECC;		/* Flag to decide whether or not to use NANDECC */
    557 
    558 	void *genericDevice;	/* Pointer to device context
    559 				 * On an mtd this holds the mtd pointer.
    560 				 */
    561         void *superBlock;
    562 
    563 	/* NAND access functions (Must be set before calling YAFFS)*/
    564 
    565 	int (*writeChunkToNAND) (struct yaffs_DeviceStruct * dev,
    566 				 int chunkInNAND, const __u8 * data,
    567 				 const yaffs_Spare * spare);
    568 	int (*readChunkFromNAND) (struct yaffs_DeviceStruct * dev,
    569 				  int chunkInNAND, __u8 * data,
    570 				  yaffs_Spare * spare);
    571 	int (*eraseBlockInNAND) (struct yaffs_DeviceStruct * dev,
    572 				 int blockInNAND);
    573 	int (*initialiseNAND) (struct yaffs_DeviceStruct * dev);
    574 
    575 #ifdef CONFIG_YAFFS_YAFFS2
    576 	int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev,
    577 					 int chunkInNAND, const __u8 * data,
    578 					 const yaffs_ExtendedTags * tags);
    579 	int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct * dev,
    580 					  int chunkInNAND, __u8 * data,
    581 					  yaffs_ExtendedTags * tags);
    582 	int (*markNANDBlockBad) (struct yaffs_DeviceStruct * dev, int blockNo);
    583 	int (*queryNANDBlock) (struct yaffs_DeviceStruct * dev, int blockNo,
    584 			       yaffs_BlockState * state, int *sequenceNumber);
    585 #endif
    586 
    587 	int isYaffs2;
    588 
    589 	/* The removeObjectCallback function must be supplied by OS flavours that
    590 	 * need it. The Linux kernel does not use this, but yaffs direct does use
    591 	 * it to implement the faster readdir
    592 	 */
    593 	void (*removeObjectCallback)(struct yaffs_ObjectStruct *obj);
    594 
    595 	/* Callback to mark the superblock dirsty */
    596 	void (*markSuperBlockDirty)(void * superblock);
    597 
    598 	int wideTnodesDisabled; /* Set to disable wide tnodes */
    599 
    600 
    601 	/* End of stuff that must be set before initialisation. */
    602 
    603 	/* Runtime parameters. Set up by YAFFS. */
    604 
    605 	__u16 chunkGroupBits;	/* 0 for devices <= 32MB. else log2(nchunks) - 16 */
    606 	__u16 chunkGroupSize;	/* == 2^^chunkGroupBits */
    607 
    608 	/* Stuff to support wide tnodes */
    609 	__u32 tnodeWidth;
    610 	__u32 tnodeMask;
    611 
    612 	/* Stuff to support various file offses to chunk/offset translations */
    613 	/* "Crumbs" for nDataBytesPerChunk not being a power of 2 */
    614 	__u32 crumbMask;
    615 	__u32 crumbShift;
    616 	__u32 crumbsPerChunk;
    617 
    618 	/* Straight shifting for nDataBytesPerChunk being a power of 2 */
    619 	__u32 chunkShift;
    620 	__u32 chunkMask;
    621 
    622 
    623 #ifdef __KERNEL__
    624 
    625 	struct semaphore sem;	/* Semaphore for waiting on erasure.*/
    626 	struct semaphore grossLock;	/* Gross locking semaphore */
    627 	__u8 *spareBuffer;	/* For mtdif2 use. Don't know the size of the buffer
    628 				 * at compile time so we have to allocate it.
    629 				 */
    630 	void (*putSuperFunc) (struct super_block * sb);
    631 #endif
    632 
    633 	int isMounted;
    634 
    635 	int isCheckpointed;
    636 
    637 
    638 	/* Stuff to support block offsetting to support start block zero */
    639 	int internalStartBlock;
    640 	int internalEndBlock;
    641 	int blockOffset;
    642 	int chunkOffset;
    643 
    644 
    645 	/* Runtime checkpointing stuff */
    646 	int checkpointPageSequence;   /* running sequence number of checkpoint pages */
    647 	int checkpointByteCount;
    648 	int checkpointByteOffset;
    649 	__u8 *checkpointBuffer;
    650 	int checkpointOpenForWrite;
    651 	int blocksInCheckpoint;
    652 	int checkpointCurrentChunk;
    653 	int checkpointCurrentBlock;
    654 	int checkpointNextBlock;
    655 	int *checkpointBlockList;
    656 	int checkpointMaxBlocks;
    657 
    658 	/* Block Info */
    659 	yaffs_BlockInfo *blockInfo;
    660 	__u8 *chunkBits;	/* bitmap of chunks in use */
    661 	unsigned blockInfoAlt:1;	/* was allocated using alternative strategy */
    662 	unsigned chunkBitsAlt:1;	/* was allocated using alternative strategy */
    663 	int chunkBitmapStride;	/* Number of bytes of chunkBits per block.
    664 				 * Must be consistent with nChunksPerBlock.
    665 				 */
    666 
    667 	int nErasedBlocks;
    668 	int allocationBlock;	/* Current block being allocated off */
    669 	__u32 allocationPage;
    670 	int allocationBlockFinder;	/* Used to search for next allocation block */
    671 
    672 	/* Runtime state */
    673 	int nTnodesCreated;
    674 	yaffs_Tnode *freeTnodes;
    675 	int nFreeTnodes;
    676 	yaffs_TnodeList *allocatedTnodeList;
    677 
    678 	int isDoingGC;
    679 
    680 	int nObjectsCreated;
    681 	yaffs_Object *freeObjects;
    682 	int nFreeObjects;
    683 
    684 	yaffs_ObjectList *allocatedObjectList;
    685 
    686 	yaffs_ObjectBucket objectBucket[YAFFS_NOBJECT_BUCKETS];
    687 
    688 	int nFreeChunks;
    689 
    690 	int currentDirtyChecker;	/* Used to find current dirtiest block */
    691 
    692 	__u32 *gcCleanupList;	/* objects to delete at the end of a GC. */
    693 
    694 	/* Statistcs */
    695 	int nPageWrites;
    696 	int nPageReads;
    697 	int nBlockErasures;
    698 	int nErasureFailures;
    699 	int nGCCopies;
    700 	int garbageCollections;
    701 	int passiveGarbageCollections;
    702 	int nRetriedWrites;
    703 	int nRetiredBlocks;
    704 	int eccFixed;
    705 	int eccUnfixed;
    706 	int tagsEccFixed;
    707 	int tagsEccUnfixed;
    708 	int nDeletions;
    709 	int nUnmarkedDeletions;
    710 
    711 	int hasPendingPrioritisedGCs; /* We think this device might have pending prioritised gcs */
    712 
    713 	/* Special directories */
    714 	yaffs_Object *rootDir;
    715 	yaffs_Object *lostNFoundDir;
    716 
    717 	/* Buffer areas for storing data to recover from write failures TODO
    718 	 *      __u8            bufferedData[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK];
    719 	 *      yaffs_Spare bufferedSpare[YAFFS_CHUNKS_PER_BLOCK];
    720 	 */
    721 
    722 	int bufferedBlock;	/* Which block is buffered here? */
    723 	int doingBufferedBlockRewrite;
    724 
    725 	yaffs_ChunkCache *srCache;
    726 	int srLastUse;
    727 
    728 	int cacheHits;
    729 
    730 	/* Stuff for background deletion and unlinked files.*/
    731 	yaffs_Object *unlinkedDir;	/* Directory where unlinked and deleted files live. */
    732 	yaffs_Object *deletedDir;	/* Directory where deleted objects are sent to disappear. */
    733 	yaffs_Object *unlinkedDeletion;	/* Current file being background deleted.*/
    734 	int nDeletedFiles;		/* Count of files awaiting deletion;*/
    735 	int nUnlinkedFiles;		/* Count of unlinked files. */
    736 	int nBackgroundDeletions;	/* Count of background deletions. */
    737 
    738 
    739 	yaffs_TempBuffer tempBuffer[YAFFS_N_TEMP_BUFFERS];
    740 	int maxTemp;
    741 	int unmanagedTempAllocations;
    742 	int unmanagedTempDeallocations;
    743 
    744 	/* yaffs2 runtime stuff */
    745 	unsigned sequenceNumber;	/* Sequence number of currently allocating block */
    746 	unsigned oldestDirtySequence;
    747 
    748 };
    749 
    750 typedef struct yaffs_DeviceStruct yaffs_Device;
    751 
    752 /* The static layout of bllock usage etc is stored in the super block header */
    753 typedef struct {
    754         int StructType;
    755 	int version;
    756 	int checkpointStartBlock;
    757 	int checkpointEndBlock;
    758 	int startBlock;
    759 	int endBlock;
    760 	int rfu[100];
    761 } yaffs_SuperBlockHeader;
    762 
    763 /* The CheckpointDevice structure holds the device information that changes at runtime and
    764  * must be preserved over unmount/mount cycles.
    765  */
    766 typedef struct {
    767         int structType;
    768 	int nErasedBlocks;
    769 	int allocationBlock;	/* Current block being allocated off */
    770 	__u32 allocationPage;
    771 	int nFreeChunks;
    772 
    773 	int nDeletedFiles;		/* Count of files awaiting deletion;*/
    774 	int nUnlinkedFiles;		/* Count of unlinked files. */
    775 	int nBackgroundDeletions;	/* Count of background deletions. */
    776 
    777 	/* yaffs2 runtime stuff */
    778 	unsigned sequenceNumber;	/* Sequence number of currently allocating block */
    779 	unsigned oldestDirtySequence;
    780 
    781 } yaffs_CheckpointDevice;
    782 
    783 
    784 typedef struct {
    785     int structType;
    786     __u32 magic;
    787     __u32 version;
    788     __u32 head;
    789 } yaffs_CheckpointValidity;
    790 
    791 /* Function to manipulate block info */
    792 static Y_INLINE yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blk)
    793 {
    794 	if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
    795 		T(YAFFS_TRACE_ERROR,
    796 		  (TSTR
    797 		   ("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),
    798 		   blk));
    799 		YBUG();
    800 	}
    801 	return &dev->blockInfo[blk - dev->internalStartBlock];
    802 }
    803 
    804 /*----------------------- YAFFS Functions -----------------------*/
    805 
    806 int yaffs_GutsInitialise(yaffs_Device * dev);
    807 void yaffs_Deinitialise(yaffs_Device * dev);
    808 
    809 int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev);
    810 
    811 int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName,
    812 		       yaffs_Object * newDir, const YCHAR * newName);
    813 
    814 int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name);
    815 int yaffs_DeleteFile(yaffs_Object * obj);
    816 
    817 int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize);
    818 int yaffs_GetObjectFileLength(yaffs_Object * obj);
    819 int yaffs_GetObjectInode(yaffs_Object * obj);
    820 unsigned yaffs_GetObjectType(yaffs_Object * obj);
    821 int yaffs_GetObjectLinkCount(yaffs_Object * obj);
    822 
    823 int yaffs_SetAttributes(yaffs_Object * obj, struct iattr *attr);
    824 int yaffs_GetAttributes(yaffs_Object * obj, struct iattr *attr);
    825 
    826 /* File operations */
    827 int yaffs_ReadDataFromFile(yaffs_Object * obj, __u8 * buffer, loff_t offset,
    828 			   int nBytes);
    829 int yaffs_WriteDataToFile(yaffs_Object * obj, const __u8 * buffer, loff_t offset,
    830 			  int nBytes, int writeThrough);
    831 int yaffs_ResizeFile(yaffs_Object * obj, loff_t newSize);
    832 
    833 yaffs_Object *yaffs_MknodFile(yaffs_Object * parent, const YCHAR * name,
    834 			      __u32 mode, __u32 uid, __u32 gid);
    835 int yaffs_FlushFile(yaffs_Object * obj, int updateTime);
    836 
    837 /* Flushing and checkpointing */
    838 void yaffs_FlushEntireDeviceCache(yaffs_Device *dev);
    839 
    840 int yaffs_CheckpointSave(yaffs_Device *dev);
    841 int yaffs_CheckpointRestore(yaffs_Device *dev);
    842 
    843 /* Directory operations */
    844 yaffs_Object *yaffs_MknodDirectory(yaffs_Object * parent, const YCHAR * name,
    845 				   __u32 mode, __u32 uid, __u32 gid);
    846 yaffs_Object *yaffs_FindObjectByName(yaffs_Object * theDir, const YCHAR * name);
    847 int yaffs_ApplyToDirectoryChildren(yaffs_Object * theDir,
    848 				   int (*fn) (yaffs_Object *));
    849 
    850 yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device * dev, __u32 number);
    851 
    852 /* Link operations */
    853 yaffs_Object *yaffs_Link(yaffs_Object * parent, const YCHAR * name,
    854 			 yaffs_Object * equivalentObject);
    855 
    856 yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object * obj);
    857 
    858 /* Symlink operations */
    859 yaffs_Object *yaffs_MknodSymLink(yaffs_Object * parent, const YCHAR * name,
    860 				 __u32 mode, __u32 uid, __u32 gid,
    861 				 const YCHAR * alias);
    862 YCHAR *yaffs_GetSymlinkAlias(yaffs_Object * obj);
    863 
    864 /* Special inodes (fifos, sockets and devices) */
    865 yaffs_Object *yaffs_MknodSpecial(yaffs_Object * parent, const YCHAR * name,
    866 				 __u32 mode, __u32 uid, __u32 gid, __u32 rdev);
    867 
    868 /* Special directories */
    869 yaffs_Object *yaffs_Root(yaffs_Device * dev);
    870 yaffs_Object *yaffs_LostNFound(yaffs_Device * dev);
    871 
    872 #ifdef CONFIG_YAFFS_WINCE
    873 /* CONFIG_YAFFS_WINCE special stuff */
    874 void yfsd_WinFileTimeNow(__u32 target[2]);
    875 #endif
    876 
    877 #ifdef __KERNEL__
    878 
    879 void yaffs_HandleDeferedFree(yaffs_Object * obj);
    880 #endif
    881 
    882 /* Debug dump  */
    883 int yaffs_DumpObject(yaffs_Object * obj);
    884 
    885 void yaffs_GutsTest(yaffs_Device * dev);
    886 
    887 /* A few useful functions */
    888 void yaffs_InitialiseTags(yaffs_ExtendedTags * tags);
    889 void yaffs_DeleteChunk(yaffs_Device * dev, int chunkId, int markNAND, int lyn);
    890 int yaffs_CheckFF(__u8 * buffer, int nBytes);
    891 void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi);
    892 
    893 #endif
    894