Change blockState field from enum to unsigned because some compilers use ints for...
[yaffs2.git] / yaffs_guts.h
index 2da744940b09698983394d54dd68979915005679..b7803151fe933e3783ad1fdd002c9bfc90625de6 100644 (file)
@@ -1,8 +1,7 @@
 /*
- * YAFFS: Yet another FFS. A NAND-flash specific file system.
- * yaffs_guts.h: Configuration etc for yaffs_guts
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. 
  *
- * Copyright (C) 2002 Aleph One Ltd.
+ * Copyright (C) 2002-2007 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
  * it under the terms of the GNU Lesser General Public License version 2.1 as
  * published by the Free Software Foundation.
  *
- *
  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
- *
- * $Id: yaffs_guts.h,v 1.21 2006-05-08 10:13:34 charles Exp $
  */
 
 #ifndef __YAFFS_GUTS_H__
@@ -67,7 +63,7 @@
 
 #define YAFFS_OBJECT_SPACE             0x40000
 
-#define YAFFS_NCHECKPOINT_OBJECTS      5000
+#define YAFFS_CHECKPOINT_VERSION       3
 
 #ifdef CONFIG_YAFFS_UNICODE
 #define YAFFS_MAX_NAME_LENGTH          127
@@ -88,6 +84,7 @@
 /* Sseudo object ids for checkpointing */
 #define YAFFS_OBJECTID_SB_HEADER       0x10
 #define YAFFS_OBJECTID_CHECKPOINT_DATA 0x20
+#define YAFFS_SEQUENCE_CHECKPOINT_DATA  0x21
 
 /* */
 
@@ -163,6 +160,8 @@ typedef enum {
        YAFFS_OBJECT_TYPE_SPECIAL
 } yaffs_ObjectType;
 
+#define YAFFS_OBJECT_TYPE_MAX YAFFS_OBJECT_TYPE_SPECIAL
+
 typedef struct {
 
        unsigned validMarker0;
@@ -240,13 +239,13 @@ typedef enum {
 
        YAFFS_BLOCK_STATE_ALLOCATING,
        /* This block is partially allocated. 
+        * At least one page holds valid data.
         * This is the one currently being used for page
         * allocation. Should never be more than one of these
         */
 
        YAFFS_BLOCK_STATE_FULL, 
        /* All the pages in this block have been allocated.
-        * At least one page holds valid data.
         */
 
        YAFFS_BLOCK_STATE_DIRTY,
@@ -254,6 +253,10 @@ typedef enum {
         * Erase me, reuse me.
         */
 
+       YAFFS_BLOCK_STATE_CHECKPOINT,   
+       /* This block is assigned to holding checkpoint data.
+        */
+
        YAFFS_BLOCK_STATE_COLLECTING,   
        /* This block is being garbage collected */
 
@@ -261,13 +264,21 @@ typedef enum {
        /* This block has failed and is not in use */
 } yaffs_BlockState;
 
+#define        YAFFS_NUMBER_OF_BLOCK_STATES (YAFFS_BLOCK_STATE_DEAD + 1)
+
+
 typedef struct {
 
-       int softDeletions:12;   /* number of soft deleted pages */
-       int pagesInUse:12;      /* number of pages in use */
-       yaffs_BlockState blockState:4;  /* One of the above block states */
+       int softDeletions:10;   /* number of soft deleted pages */
+       int pagesInUse:10;      /* number of pages in use */
+       __u32 blockState:4;     /* One of the above block states. NB use unsigned because enum is sometimes an int */
        __u32 needsRetiring:1;  /* Data has failed on this block, need to get valid data off */
                                /* and retire the block. */
+       __u32 skipErasedCheck: 1; /* If this is set we can skip the erased check on this block */
+       __u32 gcPrioritise: 1;  /* An ECC check or blank check has failed on this block. 
+                                  It should be prioritised for GC */
+        __u32 chunkErrorStrikes:3; /* How many times we've had ecc etc failures on this block and tried to reuse it */
+
 #ifdef CONFIG_YAFFS_YAFFS2
        __u32 hasShrinkHeader:1; /* This block has at least one shrink object header */
        __u32 sequenceNumber;    /* block sequence number for yaffs2 */
@@ -515,17 +526,19 @@ struct yaffs_DeviceStruct {
        const char *name;
 
        /* Entry parameters set up way early. Yaffs sets up the rest.*/
-       int nBytesPerChunk;     /* Should be a power of 2 >= 512 */
+       int nDataBytesPerChunk; /* Should be a power of 2 >= 512 */
        int nChunksPerBlock;    /* does not need to be a power of 2 */
        int nBytesPerSpare;     /* spare area size */
        int startBlock;         /* Start block we're allowed to use */
        int endBlock;           /* End block we're allowed to use */
        int nReservedBlocks;    /* We want this tuneable so that we can reduce */
                                /* reserved blocks on NOR and RAM. */
-       /* Stuff used by checkpointing */
-       int headerBlock;
-       int checkpointStartBlock;
-       int checkpointEndBlock;
+       
+       
+       /* Stuff used by the shared space checkpointing mechanism */
+       /* If this value is zero, then this mechanism is disabled */
+       
+       int nCheckpointReservedBlocks; /* Blocks to reserve for checkpoint data */
 
        
 
@@ -541,6 +554,8 @@ struct yaffs_DeviceStruct {
        void *genericDevice;    /* Pointer to device context
                                 * On an mtd this holds the mtd pointer.
                                 */
+        void *superBlock;
+        
        /* NAND access functions (Must be set before calling YAFFS)*/
 
        int (*writeChunkToNAND) (struct yaffs_DeviceStruct * dev,
@@ -573,10 +588,17 @@ struct yaffs_DeviceStruct {
         */
        void (*removeObjectCallback)(struct yaffs_ObjectStruct *obj);
        
+       /* Callback to mark the superblock dirsty */
+       void (*markSuperBlockDirty)(void * superblock);
+       
        int wideTnodesDisabled; /* Set to disable wide tnodes */
        
 
        /* End of stuff that must be set before initialisation. */
+       
+       /* Checkpoint control. Can be set before or after initialisation */
+       __u8 skipCheckpointRead;
+       __u8 skipCheckpointWrite;
 
        /* Runtime parameters. Set up by YAFFS. */
 
@@ -587,6 +609,16 @@ struct yaffs_DeviceStruct {
        __u32 tnodeWidth;
        __u32 tnodeMask;
        
+       /* Stuff to support various file offses to chunk/offset translations */
+       /* "Crumbs" for nDataBytesPerChunk not being a power of 2 */
+       __u32 crumbMask;
+       __u32 crumbShift;
+       __u32 crumbsPerChunk;
+       
+       /* Straight shifting for nDataBytesPerChunk being a power of 2 */
+       __u32 chunkShift;
+       __u32 chunkMask;
+       
 
 #ifdef __KERNEL__
 
@@ -602,6 +634,7 @@ struct yaffs_DeviceStruct {
        
        int isCheckpointed;
 
+
        /* Stuff to support block offsetting to support start block zero */
        int internalStartBlock;
        int internalEndBlock;
@@ -610,12 +643,19 @@ struct yaffs_DeviceStruct {
        
 
        /* Runtime checkpointing stuff */
-       int checkpointBlock;
-       int checkpointPage;
+       int checkpointPageSequence;   /* running sequence number of checkpoint pages */
        int checkpointByteCount;
        int checkpointByteOffset;
        __u8 *checkpointBuffer;
        int checkpointOpenForWrite;
+       int blocksInCheckpoint;
+       int checkpointCurrentChunk;
+       int checkpointCurrentBlock;
+       int checkpointNextBlock;
+       int *checkpointBlockList;
+       int checkpointMaxBlocks;
+       __u32 checkpointSum;
+       __u32 checkpointXor;
        
        /* Block Info */
        yaffs_BlockInfo *blockInfo;
@@ -669,6 +709,8 @@ struct yaffs_DeviceStruct {
        int tagsEccUnfixed;
        int nDeletions;
        int nUnmarkedDeletions;
+       
+       int hasPendingPrioritisedGCs; /* We think this device might have pending prioritised gcs */
 
        /* Special directories */
        yaffs_Object *rootDir;
@@ -784,11 +826,11 @@ int yaffs_SetAttributes(yaffs_Object * obj, struct iattr *attr);
 int yaffs_GetAttributes(yaffs_Object * obj, struct iattr *attr);
 
 /* File operations */
-int yaffs_ReadDataFromFile(yaffs_Object * obj, __u8 * buffer, __u32 offset,
+int yaffs_ReadDataFromFile(yaffs_Object * obj, __u8 * buffer, loff_t offset,
                           int nBytes);
-int yaffs_WriteDataToFile(yaffs_Object * obj, const __u8 * buffer, __u32 offset,
+int yaffs_WriteDataToFile(yaffs_Object * obj, const __u8 * buffer, loff_t offset,
                          int nBytes, int writeThrough);
-int yaffs_ResizeFile(yaffs_Object * obj, int newSize);
+int yaffs_ResizeFile(yaffs_Object * obj, loff_t newSize);
 
 yaffs_Object *yaffs_MknodFile(yaffs_Object * parent, const YCHAR * name,
                              __u32 mode, __u32 uid, __u32 gid);
@@ -848,5 +890,6 @@ void yaffs_GutsTest(yaffs_Device * dev);
 void yaffs_InitialiseTags(yaffs_ExtendedTags * tags);
 void yaffs_DeleteChunk(yaffs_Device * dev, int chunkId, int markNAND, int lyn);
 int yaffs_CheckFF(__u8 * buffer, int nBytes);
+void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi);
 
 #endif