summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorCharles Manning <cdhmanning@gmail.com>2009-10-30 12:08:15 +1300
committerArve Hjønnevåg <arve@android.com>2010-02-08 15:09:11 -0800
commit8ff4860c2778c0be92a63808036de337d13fa864 (patch)
tree4dc9cb73e95579f1703e29e37f38503535da8289 /fs
parent4698f1ee43795d9b4b2c6a91c84e000c9bfee21b (diff)
Fix yaffs checkpoint out of space crash
An ealy return from checkpoint opening caused the writing flag to be set incorrectly which caused the wrong execution path during the close. Also clean up space left behind by aborted checkpoints. Also jsut neaten up NULL handling. Signed-off-by: Charles Manning <cdhmanning@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/yaffs2/yaffs_checkptrw.c26
-rw-r--r--fs/yaffs2/yaffs_guts.c3
2 files changed, 15 insertions, 14 deletions
diff --git a/fs/yaffs2/yaffs_checkptrw.c b/fs/yaffs2/yaffs_checkptrw.c
index 66a4e7d9f0f9..7b69a640f4b0 100644
--- a/fs/yaffs2/yaffs_checkptrw.c
+++ b/fs/yaffs2/yaffs_checkptrw.c
@@ -130,6 +130,9 @@ static void yaffs_CheckpointFindNextCheckpointBlock(yaffs_Device *dev)
int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
{
+
+ dev->checkpointOpenForWrite = forWriting;
+
/* Got the functions we need? */
if (!dev->writeChunkWithTagsToNAND ||
!dev->readChunkWithTagsFromNAND ||
@@ -147,9 +150,6 @@ int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
dev->checkpointPageSequence = 0;
-
- dev->checkpointOpenForWrite = forWriting;
-
dev->checkpointByteCount = 0;
dev->checkpointSum = 0;
dev->checkpointXor = 0;
@@ -358,11 +358,14 @@ int yaffs_CheckpointClose(yaffs_Device *dev)
if (dev->checkpointOpenForWrite) {
if (dev->checkpointByteOffset != 0)
yaffs_CheckpointFlushBuffer(dev);
- } else {
+ } else if(dev->checkpointBlockList){
int i;
for (i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++) {
- yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, dev->checkpointBlockList[i]);
- if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY)
+ int blk = dev->checkpointBlockList[i];
+ yaffs_BlockInfo *bi = NULL;
+ if( dev->internalStartBlock <= blk && blk <= dev->internalEndBlock)
+ bi = yaffs_GetBlockInfo(dev, blk);
+ if (bi && bi->blockState == YAFFS_BLOCK_STATE_EMPTY)
bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
else {
/* Todo this looks odd... */
@@ -390,15 +393,10 @@ int yaffs_CheckpointClose(yaffs_Device *dev)
int yaffs_CheckpointInvalidateStream(yaffs_Device *dev)
{
- /* Erase the first checksum block */
-
- T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint invalidate"TENDSTR)));
+ /* Erase the checkpoint data */
- if (!yaffs_CheckpointSpaceOk(dev))
- return 0;
+ T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint invalidate of %d blocks"TENDSTR),
+ dev->blocksInCheckpoint));
return yaffs_CheckpointErase(dev);
}
-
-
-
diff --git a/fs/yaffs2/yaffs_guts.c b/fs/yaffs2/yaffs_guts.c
index 155b74643eb8..05ff48d1bc46 100644
--- a/fs/yaffs2/yaffs_guts.c
+++ b/fs/yaffs2/yaffs_guts.c
@@ -7436,6 +7436,9 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
yaffs_VerifyFreeChunks(dev);
yaffs_VerifyBlocks(dev);
+ /* Clean up any aborted checkpoint data */
+ if (!dev->isCheckpointed && dev->blocksInCheckpoint > 0)
+ yaffs_InvalidateCheckpoint(dev);
T(YAFFS_TRACE_TRACING,
(TSTR("yaffs: yaffs_GutsInitialise() done.\n" TENDSTR)));