~ubuntu-branches/ubuntu/maverick/u-boot-omap3/maverick

« back to all changes in this revision

Viewing changes to fs/yaffs2/yaffs_guts.h

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2010-03-22 15:06:23 UTC
  • Revision ID: james.westby@ubuntu.com-20100322150623-i21g8rgiyl5dohag
Tags: upstream-2010.3git20100315
ImportĀ upstreamĀ versionĀ 2010.3git20100315

Show diffs side-by-side

added added

removed removed

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