X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.h;h=284e206040eb14c485d8fe55cf0a86307679b2f2;hp=b9b2ea19481f3237509b4ad8419cc8a45bf2cf4d;hb=7211ad39b355b558a4f8a97bc4821ee859888bd6;hpb=e8cfe05cf0d057f6978c37943e51b17bb14664e3 diff --git a/yaffs_guts.h b/yaffs_guts.h index b9b2ea1..284e206 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -1,5 +1,5 @@ /* - * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. * * Copyright (C) 2002-2007 Aleph One Ltd. * for Toby Churchill Ltd and Brightstar Engineering @@ -22,11 +22,11 @@ #define YAFFS_OK 1 #define YAFFS_FAIL 0 -/* Give us a Y=0x59, - * Give us an A=0x41, - * Give us an FF=0xFF +/* Give us a Y=0x59, + * Give us an A=0x41, + * Give us an FF=0xFF * Give us an S=0x53 - * And what have we got... + * And what have we got... */ #define YAFFS_MAGIC 0x5941FF53 @@ -102,12 +102,15 @@ * The range is limited slightly to help distinguish bad numbers from good. * This also allows us to perhaps in the future use special numbers for * special purposes. - * EFFFFF00 allows the allocation of 8 blocks per second (~1Mbytes) for 15 years, + * EFFFFF00 allows the allocation of 8 blocks per second (~1Mbytes) for 15 years, * and is a larger number than the lifetime of a 2GB device. */ #define YAFFS_LOWEST_SEQUENCE_NUMBER 0x00001000 #define YAFFS_HIGHEST_SEQUENCE_NUMBER 0xEFFFFF00 +/* Special sequence number for bad block that failed to be marked bad */ +#define YAFFS_SEQUENCE_BAD_BLOCK 0xFFFF0000 + /* ChunkCache is used for short read/write operations.*/ typedef struct { struct yaffs_ObjectStruct *object; @@ -132,12 +135,12 @@ typedef struct { #ifndef CONFIG_YAFFS_NO_YAFFS1 typedef struct { - unsigned chunkId:20; - unsigned serialNumber:2; - unsigned byteCount:10; - unsigned objectId:18; - unsigned ecc:12; - unsigned unusedStuff:2; + unsigned chunkId:20; + unsigned serialNumber:2; + unsigned byteCountLSB:10; + unsigned objectId:18; + unsigned ecc:12; + unsigned byteCountMSB:2; } yaffs_Tags; @@ -178,7 +181,7 @@ typedef struct { /* The following stuff only has meaning when we read */ yaffs_ECCResult eccResult; - unsigned blockBad; + unsigned blockBad; /* YAFFS 1 stuff */ unsigned chunkDeleted; /* The chunk is marked deleted */ @@ -244,29 +247,29 @@ typedef enum { /* This block is empty */ YAFFS_BLOCK_STATE_ALLOCATING, - /* This block is partially allocated. + /* 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, + YAFFS_BLOCK_STATE_FULL, /* All the pages in this block have been allocated. */ YAFFS_BLOCK_STATE_DIRTY, - /* All pages have been allocated and deleted. + /* All pages have been allocated and deleted. * Erase me, reuse me. */ - YAFFS_BLOCK_STATE_CHECKPOINT, + YAFFS_BLOCK_STATE_CHECKPOINT, /* This block is assigned to holding checkpoint data. */ - YAFFS_BLOCK_STATE_COLLECTING, + YAFFS_BLOCK_STATE_COLLECTING, /* This block is being garbage collected */ - YAFFS_BLOCK_STATE_DEAD + YAFFS_BLOCK_STATE_DEAD /* This block has failed and is not in use */ } yaffs_BlockState; @@ -281,7 +284,7 @@ typedef struct { __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. + __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 */ @@ -300,11 +303,11 @@ typedef struct { /* Apply to everything */ int parentObjectId; - __u16 sum__NoLongerUsed; /* checksum of name. No longer used */ - YCHAR name[YAFFS_MAX_NAME_LENGTH + 1]; + __u16 sum__NoLongerUsed; /* checksum of name. No longer used */ + YCHAR name[YAFFS_MAX_NAME_LENGTH + 1]; - /* The following apply to directories, files, symlinks - not hard links */ - __u32 yst_mode; /* protection */ + /* The following apply to directories, files, symlinks - not hard links */ + __u32 yst_mode; /* protection */ #ifdef CONFIG_YAFFS_WINCE __u32 notForWinCE[5]; @@ -384,7 +387,7 @@ typedef struct { } yaffs_FileStructure; typedef struct { - struct ylist_head children; /* list of child links */ + struct ylist_head children; /* list of child links */ } yaffs_DirectoryStructure; typedef struct { @@ -411,7 +414,7 @@ struct yaffs_ObjectStruct { __u8 renameAllowed:1; /* Some objects are not allowed to be renamed. */ __u8 unlinkAllowed:1; __u8 dirty:1; /* the object needs to be written to flash */ - __u8 valid:1; /* When the file system is being loaded up, this + __u8 valid:1; /* When the file system is being loaded up, this * object might be created before the data * is available (ie. file data records appear before the header). */ @@ -420,24 +423,25 @@ struct yaffs_ObjectStruct { __u8 deferedFree:1; /* For Linux kernel. Object is removed from NAND, but is * still in the inode cache. Free of object is defered. * until the inode is released. - */ + */ + __u8 beingCreated:1; /* This object is still being created so skip some checks. */ __u8 serial; /* serial number of chunk in NAND. Cached here */ __u16 sum; /* sum of the name to speed searching */ - struct yaffs_DeviceStruct *myDev; /* The device I'm on */ + struct yaffs_DeviceStruct *myDev; /* The device I'm on */ - struct ylist_head hashLink; /* list of objects in this hash bucket */ + struct ylist_head hashLink; /* list of objects in this hash bucket */ - struct ylist_head hardLinks; /* all the equivalent hard linked objects */ + struct ylist_head hardLinks; /* all the equivalent hard linked objects */ - /* directory structure stuff */ - /* also used for linking up the free list */ - struct yaffs_ObjectStruct *parent; - struct ylist_head siblings; + /* directory structure stuff */ + /* also used for linking up the free list */ + struct yaffs_ObjectStruct *parent; + struct ylist_head siblings; /* Where's my object header in NAND? */ - int chunkId; + int hdrChunk; int nDataChunks; /* Number of data chunks attached to the file. */ @@ -488,31 +492,30 @@ struct yaffs_ObjectList_struct { typedef struct yaffs_ObjectList_struct yaffs_ObjectList; typedef struct { - struct ylist_head list; - int count; + struct ylist_head list; + int count; } yaffs_ObjectBucket; -/* yaffs_CheckpointObject holds the definition of an object as dumped +/* yaffs_CheckpointObject holds the definition of an object as dumped * by checkpointing. */ typedef struct { int structType; - __u32 objectId; + __u32 objectId; __u32 parentId; - int chunkId; - + int hdrChunk; yaffs_ObjectType variantType:3; - __u8 deleted:1; - __u8 softDeleted:1; - __u8 unlinked:1; - __u8 fake:1; + __u8 deleted:1; + __u8 softDeleted:1; + __u8 unlinked:1; + __u8 fake:1; __u8 renameAllowed:1; __u8 unlinkAllowed:1; - __u8 serial; - - int nDataChunks; + __u8 serial; + + int nDataChunks; __u32 fileSizeOrEquivalentObjectId; }yaffs_CheckpointObject; @@ -531,25 +534,25 @@ typedef struct { /*----------------- Device ---------------------------------*/ struct yaffs_DeviceStruct { - struct ylist_head devList; - const char *name; - - /* Entry parameters set up way early. Yaffs sets up the rest.*/ - 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 */ + struct ylist_head devList; + const char *name; + + /* Entry parameters set up way early. Yaffs sets up the rest.*/ + int nDataBytesPerChunk; /* Should be a power of 2 >= 512 */ + int nChunksPerBlock; /* does not need to be a power of 2 */ + int spareBytesPerChunk;/* 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 the shared space checkpointing mechanism */ /* If this value is zero, then this mechanism is disabled */ - + // int nCheckpointReservedBlocks; /* Blocks to reserve for checkpoint data */ - + int nShortOpCaches; /* If <= 0, then short op caching is disabled, else @@ -564,7 +567,7 @@ struct yaffs_DeviceStruct { * 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,9 +576,10 @@ struct yaffs_DeviceStruct { int (*readChunkFromNAND) (struct yaffs_DeviceStruct * dev, int chunkInNAND, __u8 * data, yaffs_Spare * spare); - int (*eraseBlockInNAND) (struct yaffs_DeviceStruct * dev, - int blockInNAND); - int (*initialiseNAND) (struct yaffs_DeviceStruct * dev); + int (*eraseBlockInNAND) (struct yaffs_DeviceStruct * dev, + int blockInNAND); + int (*initialiseNAND) (struct yaffs_DeviceStruct * dev); + int (*deinitialiseNAND) (struct yaffs_DeviceStruct * dev); #ifdef CONFIG_YAFFS_YAFFS2 int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev, @@ -590,22 +594,23 @@ struct yaffs_DeviceStruct { #endif int isYaffs2; - - /* The removeObjectCallback function must be supplied by OS flavours that + + /* The removeObjectCallback function must be supplied by OS flavours that * need it. The Linux kernel does not use this, but yaffs direct does use * it to implement the faster readdir */ void (*removeObjectCallback)(struct yaffs_ObjectStruct *obj); - + /* Callback to mark the superblock dirsty */ void (*markSuperBlockDirty)(void * superblock); - + int wideTnodesDisabled; /* Set to disable wide tnodes */ YCHAR *pathDividers; /* String of legal path dividers */ + /* End of stuff that must be set before initialisation. */ - + /* Checkpoint control. Can be set before or after initialisation */ __u8 skipCheckpointRead; __u8 skipCheckpointWrite; @@ -614,11 +619,11 @@ struct yaffs_DeviceStruct { __u16 chunkGroupBits; /* 0 for devices <= 32MB. else log2(nchunks) - 16 */ __u16 chunkGroupSize; /* == 2^^chunkGroupBits */ - + /* Stuff to support wide tnodes */ __u32 tnodeWidth; __u32 tnodeMask; - + /* Stuff for figuring out file offset to chunk conversions */ __u32 chunkShift; /* Shift value */ __u32 chunkDiv; /* Divisor after shifting: 1 for power-of-2 sizes */ @@ -632,14 +637,14 @@ struct yaffs_DeviceStruct { struct semaphore sem; /* Semaphore for waiting on erasure.*/ struct semaphore grossLock; /* Gross locking semaphore */ - __u8 *spareBuffer; /* For mtdif2 use. Don't know the size of the buffer + __u8 *spareBuffer; /* For mtdif2 use. Don't know the size of the buffer * at compile time so we have to allocate it. */ void (*putSuperFunc) (struct super_block * sb); #endif int isMounted; - + int isCheckpointed; @@ -648,7 +653,7 @@ struct yaffs_DeviceStruct { int internalEndBlock; int blockOffset; int chunkOffset; - + /* Runtime checkpointing stuff */ int checkpointPageSequence; /* running sequence number of checkpoint pages */ @@ -664,15 +669,15 @@ struct yaffs_DeviceStruct { int checkpointMaxBlocks; __u32 checkpointSum; __u32 checkpointXor; - + int nCheckpointBlocksRequired; /* Number of blocks needed to store current checkpoint set */ - + /* Block Info */ yaffs_BlockInfo *blockInfo; __u8 *chunkBits; /* bitmap of chunks in use */ unsigned blockInfoAlt:1; /* was allocated using alternative strategy */ unsigned chunkBitsAlt:1; /* was allocated using alternative strategy */ - int chunkBitmapStride; /* Number of bytes of chunkBits per block. + int chunkBitmapStride; /* Number of bytes of chunkBits per block. * Must be consistent with nChunksPerBlock. */ @@ -688,10 +693,14 @@ struct yaffs_DeviceStruct { yaffs_TnodeList *allocatedTnodeList; int isDoingGC; + int gcBlock; + int gcChunk; int nObjectsCreated; yaffs_Object *freeObjects; int nFreeObjects; + + int nHardLinks; yaffs_ObjectList *allocatedObjectList; @@ -720,7 +729,7 @@ struct yaffs_DeviceStruct { int tagsEccUnfixed; int nDeletions; int nUnmarkedDeletions; - + int hasPendingPrioritisedGCs; /* We think this device might have pending prioritised gcs */ /* Special directories */ @@ -731,7 +740,7 @@ struct yaffs_DeviceStruct { * __u8 bufferedData[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK]; * yaffs_Spare bufferedSpare[YAFFS_CHUNKS_PER_BLOCK]; */ - + int bufferedBlock; /* Which block is buffered here? */ int doingBufferedBlockRewrite; @@ -767,14 +776,14 @@ typedef struct yaffs_DeviceStruct yaffs_Device; /* The static layout of block usage etc is stored in the super block header */ typedef struct { int StructType; - int version; + int version; int checkpointStartBlock; int checkpointEndBlock; int startBlock; int endBlock; int rfu[100]; } yaffs_SuperBlockHeader; - + /* The CheckpointDevice structure holds the device information that changes at runtime and * must be preserved over unmount/mount cycles. */ @@ -828,13 +837,13 @@ int yaffs_GetAttributes(yaffs_Object * obj, struct iattr *attr); /* File operations */ int yaffs_ReadDataFromFile(yaffs_Object * obj, __u8 * buffer, loff_t offset, - int nBytes); + int nBytes); int yaffs_WriteDataToFile(yaffs_Object * obj, const __u8 * buffer, loff_t offset, - int nBytes, int writeThrough); + int nBytes, int writeThrough); 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); + __u32 mode, __u32 uid, __u32 gid); int yaffs_FlushFile(yaffs_Object * obj, int updateTime); /* Flushing and checkpointing */