projects
/
yaffs2.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
e1b8e63
)
Non-partitioned checkpointing; fix to cache small read/write problem
author
charles
<charles>
Wed, 17 May 2006 09:20:26 +0000
(09:20 +0000)
committer
charles
<charles>
Wed, 17 May 2006 09:20:26 +0000
(09:20 +0000)
yaffs_guts.c
patch
|
blob
|
history
diff --git
a/yaffs_guts.c
b/yaffs_guts.c
index bc4e9b9846cf31dfb7b93e6387e1c13b9d658b14..8b7ccc32ede7540f60bae1d385aac79c2347145d 100644
(file)
--- a/
yaffs_guts.c
+++ b/
yaffs_guts.c
@@
-1,5
+1,5
@@
/*
/*
- * YAFFS: Yet another FFS. A NAND-flash specific file system.
+ * YAFFS: Yet another FFS. A NAND-flash specific file system.
*
* Copyright (C) 2002 Aleph One Ltd.
* for Toby Churchill Ltd and Brightstar Engineering
*
* Copyright (C) 2002 Aleph One Ltd.
* for Toby Churchill Ltd and Brightstar Engineering
@@
-13,7
+13,7
@@
*/
const char *yaffs_guts_c_version =
*/
const char *yaffs_guts_c_version =
- "$Id: yaffs_guts.c,v 1.3
2 2006-05-08 10:13:34
charles Exp $";
+ "$Id: yaffs_guts.c,v 1.3
3 2006-05-17 09:20:26
charles Exp $";
#include "yportenv.h"
#include "yportenv.h"
@@
-1900,9
+1900,17
@@
static int yaffs_FindBlockForGarbageCollection(yaffs_Device * dev,
bi = yaffs_GetBlockInfo(dev, b);
bi = yaffs_GetBlockInfo(dev, b);
+#if 0
+ if (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT) {
+ dirtiest = b;
+ pagesInUse = 0;
+ }
+ else
+#endif
+
if (bi->blockState == YAFFS_BLOCK_STATE_FULL &&
if (bi->blockState == YAFFS_BLOCK_STATE_FULL &&
- (bi->pagesInUse - bi->softDeletions) < pagesInUse &&
- yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
+
(bi->pagesInUse - bi->softDeletions) < pagesInUse &&
+
yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
dirtiest = b;
pagesInUse = (bi->pagesInUse - bi->softDeletions);
}
dirtiest = b;
pagesInUse = (bi->pagesInUse - bi->softDeletions);
}
@@
-2028,10
+2036,20
@@
static int yaffs_FindBlockForAllocation(yaffs_Device * dev)
}
}
-
+// Check if there's space to allocate...
+// Thinks.... do we need top make this ths same as yaffs_GetFreeChunks()?
static int yaffs_CheckSpaceForAllocation(yaffs_Device * dev)
{
static int yaffs_CheckSpaceForAllocation(yaffs_Device * dev)
{
- int reservedChunks = (dev->nReservedBlocks * dev->nChunksPerBlock);
+ int reservedChunks;
+ int reservedBlocks = dev->nReservedBlocks;
+ int checkpointBlocks;
+
+ checkpointBlocks = dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint;
+ if(checkpointBlocks < 0)
+ checkpointBlocks = 0;
+
+ reservedChunks = ((reservedBlocks + checkpointBlocks) * dev->nChunksPerBlock);
+
return (dev->nFreeChunks > reservedChunks);
}
return (dev->nFreeChunks > reservedChunks);
}
@@
-2108,6
+2126,7
@@
static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block)
int retVal = YAFFS_OK;
int cleanups = 0;
int i;
int retVal = YAFFS_OK;
int cleanups = 0;
int i;
+ int isCheckpointBlock;
int chunksBefore = yaffs_GetErasedChunks(dev);
int chunksAfter;
int chunksBefore = yaffs_GetErasedChunks(dev);
int chunksAfter;
@@
-2118,6
+2137,8
@@
static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block)
yaffs_Object *object;
yaffs_Object *object;
+ isCheckpointBlock = (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT);
+
bi->blockState = YAFFS_BLOCK_STATE_COLLECTING;
T(YAFFS_TRACE_TRACING,
bi->blockState = YAFFS_BLOCK_STATE_COLLECTING;
T(YAFFS_TRACE_TRACING,
@@
-2135,7
+2156,8
@@
static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block)
dev->isDoingGC = 1;
dev->isDoingGC = 1;
- if (!yaffs_StillSomeChunkBits(dev, block)) {
+ if (isCheckpointBlock ||
+ !yaffs_StillSomeChunkBits(dev, block)) {
T(YAFFS_TRACE_TRACING,
(TSTR
("Collecting block %d that has no chunks in use" TENDSTR),
T(YAFFS_TRACE_TRACING,
(TSTR
("Collecting block %d that has no chunks in use" TENDSTR),
@@
-3387,7
+3409,7
@@
static int yaffs_CheckpointTnodeWorker(yaffs_Object * in, yaffs_Tnode * tn,
static int yaffs_WriteCheckpointTnodes(yaffs_Object *obj)
{
__u32 endMarker = ~0;
static int yaffs_WriteCheckpointTnodes(yaffs_Object *obj)
{
__u32 endMarker = ~0;
- int ok;
+ int ok
= 1
;
if(obj->variantType == YAFFS_OBJECT_TYPE_FILE){
ok = yaffs_CheckpointTnodeWorker(obj,
if(obj->variantType == YAFFS_OBJECT_TYPE_FILE){
ok = yaffs_CheckpointTnodeWorker(obj,
@@
-3539,10
+3561,10
@@
static int yaffs_WriteCheckpointData(yaffs_Device *dev)
yaffs_CheckpointClose(dev);
yaffs_CheckpointClose(dev);
-
if(ok
)
+
// if(dev->checkpointBytes
)
dev->isCheckpointed = 1;
dev->isCheckpointed = 1;
-
else
- dev->isCheckpointed = 0;
+
//
else
+
//
dev->isCheckpointed = 0;
return dev->isCheckpointed;
}
return dev->isCheckpointed;
}
@@
-3562,14
+3584,15
@@
static int yaffs_ReadCheckpointData(yaffs_Device *dev)
if(ok)
ok = yaffs_ReadCheckpointValidityMarker(dev,0);
if(ok)
ok = yaffs_ReadCheckpointValidityMarker(dev,0);
-
- if(ok)
- dev->isCheckpointed = 1;
- else
- dev->isCheckpointed = 0;
+
yaffs_CheckpointClose(dev);
yaffs_CheckpointClose(dev);
+// if(ok)
+ dev->isCheckpointed = 1;
+// else
+// dev->isCheckpointed = 0;
+
return ok ? 1 : 0;
}
return ok ? 1 : 0;
}
@@
-3579,6
+3602,8
@@
static void yaffs_InvalidateCheckpoint(yaffs_Device *dev)
if(dev->isCheckpointed){
dev->isCheckpointed = 0;
yaffs_CheckpointInvalidateStream(dev);
if(dev->isCheckpointed){
dev->isCheckpointed = 0;
yaffs_CheckpointInvalidateStream(dev);
+ if(dev->superBlock && dev->markSuperBlockDirty)
+ dev->markSuperBlockDirty(dev->superBlock);
}
}
}
}
@@
-3782,6
+3807,7
@@
int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, __u32 offset,
yaffs_ChunkCache *cache;
/* If we can't find the data in the cache, then load the cache */
cache = yaffs_FindChunkCache(in, chunk);
yaffs_ChunkCache *cache;
/* If we can't find the data in the cache, then load the cache */
cache = yaffs_FindChunkCache(in, chunk);
+
if (!cache
&& yaffs_CheckSpaceForAllocation(in->
myDev)) {
if (!cache
&& yaffs_CheckSpaceForAllocation(in->
myDev)) {
@@
-3794,6
+3820,14
@@
int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, __u32 offset,
cache->
data);
}
cache->
data);
}
+ else if(cache &&
+ !cache->dirty &&
+ !yaffs_CheckSpaceForAllocation(in->myDev)){
+ /* Drop the cache if it was a read cache item and
+ * no space check has been made for it.
+ */
+ cache = NULL;
+ }
if (cache) {
yaffs_UseChunkCache(dev, cache, 1);
if (cache) {
yaffs_UseChunkCache(dev, cache, 1);
@@
-4925,11
+4959,18
@@
static int yaffs_ScanBackwards(yaffs_Device * dev)
bi->blockState = state;
bi->sequenceNumber = sequenceNumber;
bi->blockState = state;
bi->sequenceNumber = sequenceNumber;
+ if(bi->sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA)
+ bi->blockState = state = YAFFS_BLOCK_STATE_CHECKPOINT;
+
T(YAFFS_TRACE_SCAN_DEBUG,
(TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
state, sequenceNumber));
T(YAFFS_TRACE_SCAN_DEBUG,
(TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
state, sequenceNumber));
- if (state == YAFFS_BLOCK_STATE_DEAD) {
+
+ if(state == YAFFS_BLOCK_STATE_CHECKPOINT){
+ /* todo .. fix free space ? */
+
+ } else if (state == YAFFS_BLOCK_STATE_DEAD) {
T(YAFFS_TRACE_BAD_BLOCKS,
(TSTR("block %d is bad" TENDSTR), blk));
} else if (state == YAFFS_BLOCK_STATE_EMPTY) {
T(YAFFS_TRACE_BAD_BLOCKS,
(TSTR("block %d is bad" TENDSTR), blk));
} else if (state == YAFFS_BLOCK_STATE_EMPTY) {
@@
-6174,6
+6215,7
@@
int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev)
int nFree;
int nDirtyCacheChunks;
int nFree;
int nDirtyCacheChunks;
+ int blocksForCheckpoint;
#if 1
nFree = dev->nFreeChunks;
#if 1
nFree = dev->nFreeChunks;
@@
-6196,6
+6238,13
@@
int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev)
nFree -= nDirtyCacheChunks;
nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock);
nFree -= nDirtyCacheChunks;
nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock);
+
+ /* Now we figure out how much to reserve for the checkpoint and report that... */
+ blocksForCheckpoint = dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint;
+ if(blocksForCheckpoint < 0)
+ blocksForCheckpoint = 0;
+
+ nFree -= (blocksForCheckpoint * dev->nChunksPerBlock);
if (nFree < 0)
nFree = 0;
if (nFree < 0)
nFree = 0;