#define YAFFS_OBJECT_SPACE 0x40000
-#define YAFFS_NCHECKPOINT_OBJECTS 5000
-
-#define YAFFS_CHECKPOINT_VERSION 2
+#define YAFFS_CHECKPOINT_VERSION 3
#ifdef CONFIG_YAFFS_UNICODE
#define YAFFS_MAX_NAME_LENGTH 127
#define YAFFS_MAX_SHORT_OP_CACHES 20
-#define YAFFS_N_TEMP_BUFFERS 4
+#define YAFFS_N_TEMP_BUFFERS 6
+
+/* We limit the number attempts at sucessfully saving a chunk of data.
+ * Small-page devices have 32 pages per block; large-page devices have 64.
+ * Default to something in the order of 5 to 10 blocks worth of chunks.
+ */
+#define YAFFS_WR_ATTEMPTS (5*64)
/* Sequence numbers are used in YAFFS2 to determine block allocation order.
* The range is limited slightly to help distinguish bad numbers from good.
#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;
YAFFS_OBJECT_TYPE_SPECIAL
} yaffs_ObjectType;
+#define YAFFS_OBJECT_TYPE_MAX YAFFS_OBJECT_TYPE_SPECIAL
+
typedef struct {
unsigned validMarker0;
/* 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:10; /* number of soft deleted pages */
int pagesInUse:10; /* number of pages in use */
- yaffs_BlockState blockState:4; /* One of the above block states */
+ unsigned 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 bank 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 */
/* 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];
- /* Thes 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];
__u32 win_ctime[2];
__u32 win_atime[2];
__u32 win_mtime[2];
- __u32 roomToGrow[4];
#else
- __u32 roomToGrow[10];
+ __u32 roomToGrow[6];
+
#endif
+ __u32 inbandShadowsObject;
+ __u32 inbandIsShrink;
+ __u32 reservedSpace[2];
int shadowsObject; /* This object header shadows the specified object if > 0 */
/* isShrink applies to object headers written when we shrink the file (ie resize) */
} yaffs_FileStructure;
typedef struct {
- struct list_head children; /* list of child links */
+ struct ylist_head children; /* list of child links */
} yaffs_DirectoryStructure;
typedef struct {
__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 serial; /* serial number of chunk in NAND. Cached here */
- __u16 sum; /* sum of the name to speed searching */
+ __u8 serial; /* serial number of chunk in NAND. Cached here */
+/* __u16 sum_prev; */
+ __u16 sum; /* sum of the name to speed searching */
+/* __u16 sum_trailer; */
- struct yaffs_DeviceStruct *myDev; /* The device I'm on */
+ struct yaffs_DeviceStruct *myDev; /* The device I'm on */
- struct list_head hashLink; /* list of objects in this hash bucket */
+ struct ylist_head hashLink; /* list of objects in this hash bucket */
- struct list_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 list_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. */
__u32 objectId; /* the object id value */
- __u32 yst_mode;
+ __u32 yst_mode;
#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
- YCHAR shortName[YAFFS_SHORT_NAME_LENGTH + 1];
+ YCHAR shortName[YAFFS_SHORT_NAME_LENGTH + 1];
#endif
#ifndef __KERNEL__
typedef struct yaffs_ObjectList_struct yaffs_ObjectList;
typedef struct {
- struct list_head list;
- int count;
+ struct ylist_head list;
+ int count;
} yaffs_ObjectBucket;
int structType;
__u32 objectId;
__u32 parentId;
- int chunkId;
-
+ int hdrChunk;
yaffs_ObjectType variantType:3;
__u8 deleted:1;
__u8 softDeleted:1;
/*----------------- Device ---------------------------------*/
struct yaffs_DeviceStruct {
- struct list_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 partitioned checkpointing mechanism */
- 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 */
+// int nCheckpointReservedBlocks; /* Blocks to reserve for checkpoint data */
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,
+ int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev,
int chunkInNAND, const __u8 * data,
const yaffs_ExtendedTags * tags);
int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct * dev,
yaffs_ExtendedTags * tags);
int (*markNANDBlockBad) (struct yaffs_DeviceStruct * dev, int blockNo);
int (*queryNANDBlock) (struct yaffs_DeviceStruct * dev, int blockNo,
- yaffs_BlockState * state, int *sequenceNumber);
+ yaffs_BlockState * state, __u32 *sequenceNumber);
#endif
int isYaffs2;
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;
/* Runtime parameters. Set up by YAFFS. */
__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;
-
+ /* Stuff for figuring out file offset to chunk conversions */
+ __u32 chunkShift; /* Shift value */
+ __u32 chunkDiv; /* Divisor after shifting: 1 for power-of-2 sizes */
+ __u32 chunkMask; /* Mask to use for power-of-2 case */
+
+ /* Stuff to handle inband tags */
+ int inbandTags;
+ __u32 totalBytesPerChunk;
#ifdef __KERNEL__
int checkpointNextBlock;
int *checkpointBlockList;
int checkpointMaxBlocks;
+ __u32 checkpointSum;
+ __u32 checkpointXor;
+
+ int nCheckpointBlocksRequired; /* Number of blocks needed to store current checkpoint set */
/* Block Info */
yaffs_BlockInfo *blockInfo;
yaffs_TnodeList *allocatedTnodeList;
int isDoingGC;
+ int gcBlock;
+ int gcChunk;
int nObjectsCreated;
yaffs_Object *freeObjects;
int nFreeObjects;
+
+ int nHardLinks;
yaffs_ObjectList *allocatedObjectList;
int currentDirtyChecker; /* Used to find current dirtiest block */
__u32 *gcCleanupList; /* objects to delete at the end of a GC. */
+ int nonAggressiveSkip; /* GC state/mode */
/* Statistcs */
int nPageWrites;
int nUnlinkedFiles; /* Count of unlinked files. */
int nBackgroundDeletions; /* Count of background deletions. */
-
+
+ /* Temporary buffer management */
yaffs_TempBuffer tempBuffer[YAFFS_N_TEMP_BUFFERS];
int maxTemp;
+ int tempInUse;
int unmanagedTempAllocations;
int unmanagedTempDeallocations;
typedef struct yaffs_DeviceStruct yaffs_Device;
-/* The static layout of bllock usage etc is stored in the super block header */
+/* 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;
__u32 head;
} yaffs_CheckpointValidity;
-/* Function to manipulate block info */
-static Y_INLINE yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blk)
-{
- if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
- T(YAFFS_TRACE_ERROR,
- (TSTR
- ("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),
- blk));
- YBUG();
- }
- return &dev->blockInfo[blk - dev->internalStartBlock];
-}
/*----------------------- YAFFS Functions -----------------------*/
/* 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 */
int yaffs_CheckFF(__u8 * buffer, int nBytes);
void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi);
+__u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo);
+void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer, int lineNo);
+
#endif