/*
- * 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__
#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
/* Sseudo object ids for checkpointing */
#define YAFFS_OBJECTID_SB_HEADER 0x10
#define YAFFS_OBJECTID_CHECKPOINT_DATA 0x20
+#define YAFFS_SEQUENCE_CHECKPOINT_DATA 0x21
/* */
#define YAFFS_N_TEMP_BUFFERS 4
+/* 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.
* This also allows us to perhaps in the future use special numbers for
YAFFS_OBJECT_TYPE_SPECIAL
} yaffs_ObjectType;
+#define YAFFS_OBJECT_TYPE_MAX YAFFS_OBJECT_TYPE_SPECIAL
+
typedef struct {
unsigned validMarker0;
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,
* 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 */
/* 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 */
+ 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 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 */
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 */
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,
*/
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. */
__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__
int isCheckpointed;
+
/* Stuff to support block offsetting to support start block zero */
int internalStartBlock;
int internalEndBlock;
/* 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;
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 tagsEccUnfixed;
int nDeletions;
int nUnmarkedDeletions;
+
+ int hasPendingPrioritisedGCs; /* We think this device might have pending prioritised gcs */
/* Special directories */
yaffs_Object *rootDir;
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);
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