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