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