uboot/fs/yaffs2/yaffs_guts.h
<<
>>
Prefs
   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.*/
 112typedef 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
 134typedef 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
 144typedef 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
 153typedef 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
 160typedef 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
 171typedef 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 */
 207typedef 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 */
 223struct yaffs_NANDSpare {
 224        yaffs_Spare spare;
 225        int eccres1;
 226        int eccres2;
 227};
 228
 229/* Block data in RAM */
 230
 231typedef 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
 276typedef 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
 298typedef 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
 348union 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
 358typedef union yaffs_Tnode_union yaffs_Tnode;
 359
 360struct yaffs_TnodeList_struct {
 361        struct yaffs_TnodeList_struct *next;
 362        yaffs_Tnode *tnodes;
 363};
 364
 365typedef 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
 375typedef struct {
 376        __u32 fileSize;
 377        __u32 scannedFileSize;
 378        __u32 shrinkSize;
 379        int topLevel;
 380        yaffs_Tnode *top;
 381} yaffs_FileStructure;
 382
 383typedef struct {
 384        struct list_head children;      /* list of child links */
 385} yaffs_DirectoryStructure;
 386
 387typedef struct {
 388        YCHAR *alias;
 389} yaffs_SymLinkStructure;
 390
 391typedef struct {
 392        struct yaffs_ObjectStruct *equivalentObject;
 393        __u32 equivalentObjectId;
 394} yaffs_HardLinkStructure;
 395
 396typedef union {
 397        yaffs_FileStructure fileVariant;
 398        yaffs_DirectoryStructure directoryVariant;
 399        yaffs_SymLinkStructure symLinkVariant;
 400        yaffs_HardLinkStructure hardLinkVariant;
 401} yaffs_ObjectVariant;
 402
 403struct 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
 479typedef struct yaffs_ObjectStruct yaffs_Object;
 480
 481struct yaffs_ObjectList_struct {
 482        yaffs_Object *objects;
 483        struct yaffs_ObjectList_struct *next;
 484};
 485
 486typedef struct yaffs_ObjectList_struct yaffs_ObjectList;
 487
 488typedef 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
 498typedef 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
 523typedef struct {
 524        __u8 *buffer;
 525        int line;       /* track from whence this buffer was allocated */
 526        int maxLine;
 527} yaffs_TempBuffer;
 528
 529/*----------------- Device ---------------------------------*/
 530
 531struct 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
 763typedef struct yaffs_DeviceStruct yaffs_Device;
 764
 765/* The static layout of bllock usage etc is stored in the super block header */
 766typedef 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 */
 779typedef 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
 797typedef struct {
 798    int structType;
 799    __u32 magic;
 800    __u32 version;
 801    __u32 head;
 802} yaffs_CheckpointValidity;
 803
 804/* Function to manipulate block info */
 805static 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
 819int yaffs_GutsInitialise(yaffs_Device * dev);
 820void yaffs_Deinitialise(yaffs_Device * dev);
 821
 822int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev);
 823
 824int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName,
 825                       yaffs_Object * newDir, const YCHAR * newName);
 826
 827int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name);
 828int yaffs_DeleteFile(yaffs_Object * obj);
 829
 830int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize);
 831int yaffs_GetObjectFileLength(yaffs_Object * obj);
 832int yaffs_GetObjectInode(yaffs_Object * obj);
 833unsigned yaffs_GetObjectType(yaffs_Object * obj);
 834int yaffs_GetObjectLinkCount(yaffs_Object * obj);
 835
 836int yaffs_SetAttributes(yaffs_Object * obj, struct iattr *attr);
 837int yaffs_GetAttributes(yaffs_Object * obj, struct iattr *attr);
 838
 839/* File operations */
 840int yaffs_ReadDataFromFile(yaffs_Object * obj, __u8 * buffer, loff_t offset,
 841                           int nBytes);
 842int yaffs_WriteDataToFile(yaffs_Object * obj, const __u8 * buffer, loff_t offset,
 843                          int nBytes, int writeThrough);
 844int yaffs_ResizeFile(yaffs_Object * obj, loff_t newSize);
 845
 846yaffs_Object *yaffs_MknodFile(yaffs_Object * parent, const YCHAR * name,
 847                              __u32 mode, __u32 uid, __u32 gid);
 848int yaffs_FlushFile(yaffs_Object * obj, int updateTime);
 849
 850/* Flushing and checkpointing */
 851void yaffs_FlushEntireDeviceCache(yaffs_Device *dev);
 852
 853int yaffs_CheckpointSave(yaffs_Device *dev);
 854int yaffs_CheckpointRestore(yaffs_Device *dev);
 855
 856/* Directory operations */
 857yaffs_Object *yaffs_MknodDirectory(yaffs_Object * parent, const YCHAR * name,
 858                                   __u32 mode, __u32 uid, __u32 gid);
 859yaffs_Object *yaffs_FindObjectByName(yaffs_Object * theDir, const YCHAR * name);
 860int yaffs_ApplyToDirectoryChildren(yaffs_Object * theDir,
 861                                   int (*fn) (yaffs_Object *));
 862
 863yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device * dev, __u32 number);
 864
 865/* Link operations */
 866yaffs_Object *yaffs_Link(yaffs_Object * parent, const YCHAR * name,
 867                         yaffs_Object * equivalentObject);
 868
 869yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object * obj);
 870
 871/* Symlink operations */
 872yaffs_Object *yaffs_MknodSymLink(yaffs_Object * parent, const YCHAR * name,
 873                                 __u32 mode, __u32 uid, __u32 gid,
 874                                 const YCHAR * alias);
 875YCHAR *yaffs_GetSymlinkAlias(yaffs_Object * obj);
 876
 877/* Special inodes (fifos, sockets and devices) */
 878yaffs_Object *yaffs_MknodSpecial(yaffs_Object * parent, const YCHAR * name,
 879                                 __u32 mode, __u32 uid, __u32 gid, __u32 rdev);
 880
 881/* Special directories */
 882yaffs_Object *yaffs_Root(yaffs_Device * dev);
 883yaffs_Object *yaffs_LostNFound(yaffs_Device * dev);
 884
 885#ifdef CONFIG_YAFFS_WINCE
 886/* CONFIG_YAFFS_WINCE special stuff */
 887void yfsd_WinFileTimeNow(__u32 target[2]);
 888#endif
 889
 890/* XXX U-BOOT XXX */
 891#if 0
 892#ifndef __KERNEL__
 893void yaffs_HandleDeferedFree(yaffs_Object * obj);
 894#endif
 895#endif
 896
 897/* Debug dump  */
 898int yaffs_DumpObject(yaffs_Object * obj);
 899
 900void yaffs_GutsTest(yaffs_Device * dev);
 901
 902/* A few useful functions */
 903void yaffs_InitialiseTags(yaffs_ExtendedTags * tags);
 904void yaffs_DeleteChunk(yaffs_Device * dev, int chunkId, int markNAND, int lyn);
 905int yaffs_CheckFF(__u8 * buffer, int nBytes);
 906void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi);
 907
 908#endif
 909