changeset 138:c467501bb58c

Fix problem with checkpoint free space handling
author charles
date Tue, 23 May 2006 20:08:41 +0100
parents 62488e7b581f
children f9d57534a6bd
files direct/dtest.c direct/yaffscfg2k.c yaffs_checkptrw.c
diffstat 3 files changed, 105 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/direct/dtest.c
+++ b/direct/dtest.c
@@ -1769,7 +1769,7 @@ void checkpoint_fill_test(const char *mo
 		
 		yaffs_close(h);
 		
-		for(j = 0; j < 100; j++){
+		for(j = 0; j < 2; j++){
 			printf("touch %d\n",j);
 			yaffs_touch(b);
 			yaffs_unmount(mountpt);
@@ -1782,6 +1782,95 @@ void checkpoint_fill_test(const char *mo
 }
 
 
+int make_file2(const char *name1, const char *name2,int syz)
+{
+
+	char xx[2500];
+	int i;
+	int h1=-1,h2=-1;
+	int n = 1;
+
+
+	if(name1)
+		h1 = yaffs_open(name1,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
+	if(name2)
+		h2 = yaffs_open(name2,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
+	
+	while(syz > 0 && n > 0){
+		i = (syz > 2500) ? 2500 : syz;
+		n = yaffs_write(h1,xx,i);
+		n = yaffs_write(h2,xx,i);
+		syz -= 500;
+	}
+	yaffs_close(h1);
+	yaffs_close(h2);
+	
+}
+
+
+extern void SetCheckpointReservedBlocks(int n);
+
+void checkpoint_upgrade_test(const char *mountpt,int nmounts)
+{
+
+	char a[50];
+	char b[50];
+	char c[50];
+	char d[50];
+	
+	int i;
+	int j;
+	int h;
+	
+	sprintf(a,"%s/a",mountpt);
+	
+
+	
+	
+	printf("Create start condition\n");
+	yaffs_StartUp();
+	SetCheckpointReservedBlocks(0);
+	yaffs_mount(mountpt);
+	yaffs_mkdir(a,0);
+	sprintf(b,"%s/zz",a);
+	sprintf(c,"%s/xx",a);
+	make_file2(b,c,2000000);
+	sprintf(d,"%s/aa",a);
+	make_file2(d,NULL,500000000);
+	dump_directory_tree(mountpt);
+	
+	printf("Umount/mount attempt full\n");
+	yaffs_unmount(mountpt);
+	
+	SetCheckpointReservedBlocks(10);
+	yaffs_mount(mountpt);
+	
+	printf("unlink small file\n");
+	yaffs_unlink(c);
+	dump_directory_tree(mountpt);
+		
+	printf("Umount/mount attempt\n");
+	yaffs_unmount(mountpt);
+	yaffs_mount(mountpt);
+	
+	for(j = 0; j < 500; j++){
+		printf("***** touch %d\n",j);
+		dump_directory_tree(mountpt);
+		yaffs_touch(b);
+		yaffs_unmount(mountpt);
+		yaffs_mount(mountpt);
+	}
+
+	for(j = 0; j < 500; j++){
+		printf("***** touch %d\n",j);
+		dump_directory_tree(mountpt);
+		yaffs_touch(b);
+		yaffs_unmount(mountpt);
+		yaffs_mount(mountpt);
+	}
+}
+	
+
 
 int main(int argc, char *argv[])
 {
@@ -1800,7 +1889,8 @@ int main(int argc, char *argv[])
 	 //scan_pattern_test("/flash",10000,10);
 	//short_scan_test("/flash/flash",40000,200);
 	 //multi_mount_test("/flash/flash",20);
-	 checkpoint_fill_test("/flash/flash",20);
+	 //checkpoint_fill_test("/flash/flash",20);
+	 checkpoint_upgrade_test("/flash/flash",20);
 
 
 	
--- a/direct/yaffscfg2k.c
+++ b/direct/yaffscfg2k.c
@@ -13,7 +13,7 @@
 
 #include <errno.h>
 
-unsigned yaffs_traceMask = YAFFS_TRACE_SCAN |  YAFFS_TRACE_GC | YAFFS_TRACE_GC_DETAIL | YAFFS_TRACE_WRITE | YAFFS_TRACE_ERASE | YAFFS_TRACE_TRACING | YAFFS_TRACE_ALLOCATE | YAFFS_TRACE_CHECKPOINT;
+unsigned yaffs_traceMask = YAFFS_TRACE_SCAN |  YAFFS_TRACE_GC /*| YAFFS_TRACE_GC_DETAIL | YAFFS_TRACE_WRITE */ | YAFFS_TRACE_ERASE | YAFFS_TRACE_TRACING | YAFFS_TRACE_ALLOCATE | YAFFS_TRACE_CHECKPOINT;
 
 
 void yaffsfs_SetError(int err)
@@ -171,4 +171,8 @@ int yaffs_StartUp(void)
 
 
 
+void SetCheckpointReservedBlocks(int n)
+{
+	flashDev.nCheckpointReservedBlocks = n;
+}
 
--- a/yaffs_checkptrw.c
+++ b/yaffs_checkptrw.c
@@ -80,7 +80,6 @@ static void yaffs_CheckpointFindNextEras
 			yaffs_BlockInfo *bi = &dev->blockInfo[i];
 			if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY){
 				dev->checkpointNextBlock = i + 1;
-				dev->nErasedBlocks--;
 				dev->checkpointCurrentBlock = i;
 				T(YAFFS_TRACE_CHECKPOINT,(TSTR("allocating checkpt block %d"TENDSTR),i));
 				return;
@@ -136,7 +135,7 @@ int yaffs_CheckpointOpen(yaffs_Device *d
 		return 0;
 			
 	if(!dev->checkpointBuffer)
-		dev->checkpointBuffer = YMALLOC(dev->nBytesPerChunk);
+		dev->checkpointBuffer = YMALLOC_DMA(dev->nBytesPerChunk);
 	if(!dev->checkpointBuffer)
 		return 0;
 
@@ -193,6 +192,13 @@ static int yaffs_CheckpointFlushBuffer(y
 	tags.chunkId = dev->checkpointPageSequence + 1;
 	tags.sequenceNumber =  YAFFS_SEQUENCE_CHECKPOINT_DATA;
 	tags.byteCount = dev->nBytesPerChunk;
+	if(dev->checkpointCurrentChunk == 0){
+		/* First chunk we write for the block? Set block state to
+		   checkpoint */
+		yaffs_BlockInfo *bi = &dev->blockInfo[dev->checkpointCurrentBlock];
+		bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
+		dev->blocksInCheckpoint++;
+	}
 	
 	chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock + dev->checkpointCurrentChunk;