changeset 168:da300036f023

Fix issue with rescan of pending retired blocks
author charles
date Tue, 14 Nov 2006 03:07:17 +0000
parents d6bcfc56f939
children ad450f15459c
files direct/dtest.c yaffs_guts.c
diffstat 2 files changed, 94 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/direct/dtest.c
+++ b/direct/dtest.c
@@ -1866,6 +1866,68 @@ void small_mount_test(const char *mountp
 }
 
 
+int early_exit;
+
+void small_overwrite_test(const char *mountpt,int nmounts)
+{
+
+	char a[30];
+	char b[30];
+	char c[30];
+	
+	int i;
+	int j;
+
+	int h0;
+	int h1;
+	int len0;
+	int len1;
+	int nread;
+	
+	sprintf(a,"%s/a",mountpt);
+
+	yaffs_StartUp();
+	
+	
+	
+	for(i = 0; i < nmounts; i++){
+		
+		static char xx[8000];
+		
+		printf("############### Iteration %d   Start\n",i);
+		if(1)
+			yaffs_mount(mountpt);
+
+		dump_directory_tree(mountpt);
+		
+		yaffs_mkdir(a,0);
+		
+		sprintf(xx,"%s/0",a);
+		h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
+		sprintf(xx,"%s/1",a);
+		h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
+		
+		for(j = 0; j < 1000000; j+=1000){
+			yaffs_truncate(h0,j);
+			yaffs_lseek(h0,j,SEEK_SET);
+			yaffs_write(h0,xx,7000);
+			yaffs_write(h1,xx,7000);
+			
+			if(early_exit)
+				exit(0);
+		}
+		
+		yaffs_close(h0);
+		
+		printf("########### %d\n",i);
+		dump_directory_tree(mountpt);
+
+		if(1)
+			yaffs_unmount(mountpt);
+	}
+}
+
+
 void yaffs_touch(const char *fn)
 {
 	yaffs_chmod(fn, S_IREAD | S_IWRITE);
@@ -2071,7 +2133,8 @@ int main(int argc, char *argv[])
 	 
 	 //scan_pattern_test("/flash",10000,10);
 	//short_scan_test("/flash/flash",40000,200);
-	  small_mount_test("/flash/flash",1000);
+	  //small_mount_test("/flash/flash",1000);
+	  small_overwrite_test("/flash/flash",1000);
 	 //checkpoint_fill_test("/flash/flash",20);
 	 //checkpoint_upgrade_test("/flash/flash",20);
 	 // huge_array_test("/flash/flash",10);
--- a/yaffs_guts.c
+++ b/yaffs_guts.c
@@ -5420,39 +5420,41 @@ static int yaffs_ScanBackwards(yaffs_Dev
 					state = YAFFS_BLOCK_STATE_EMPTY;
 					dev->nErasedBlocks++;
 				} else {
-					/* this is the block being allocated from */
-					if (state ==
-					    YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
-						T(YAFFS_TRACE_SCAN,
-						  (TSTR
-						   (" Allocating from %d %d"
-						    TENDSTR), blk, c));
+					if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
+					    state == YAFFS_BLOCK_STATE_ALLOCATING) {
+					    	if(dev->sequenceNumber == bi->sequenceNumber) {
+							/* this is the block being allocated from */
+					    	
+							T(YAFFS_TRACE_SCAN,
+							  (TSTR
+							   (" Allocating from %d %d"
+							    TENDSTR), blk, c));
+
+							state = YAFFS_BLOCK_STATE_ALLOCATING;
+							dev->allocationBlock = blk;
+							dev->allocationPage = c;
+							dev->allocationBlockFinder = blk;	
+						}
+						else {
+							/* This is a partially written block that is not
+							 * the current allocation block. This block must have
+							 * had a write failure, so set up for retirement.
+							 */
+						  
+							 bi->needsRetiring = 1;
+							 bi->gcPrioritise = 1;
+							 						 
+							 T(YAFFS_TRACE_ALWAYS,
+							 (TSTR("Partially written block %d being set for retirement" TENDSTR),
+							 blk));
+						}
+
 					}
-					state = YAFFS_BLOCK_STATE_ALLOCATING;
-					dev->allocationBlock = blk;
-					dev->allocationPage = c;
-					dev->allocationBlockFinder = blk;	
-					/* Set it to here to encourage the allocator to 
-					 *  go forth from here.
-					 */
 					 
-					/* Yaffs2 sanity check:
-					 * This should be the one with the highest sequence number
-					 */
-					if (dev->isYaffs2
-					    && (dev->sequenceNumber !=
-						bi->sequenceNumber)) {
-						T(YAFFS_TRACE_ALWAYS,
-						  (TSTR
-						   ("yaffs: Allocation block %d was not highest sequence "
-						    "id: block seq = %d, dev seq = %d"
-						    TENDSTR), blk,
-						   bi->sequenceNumber,
-						   dev->sequenceNumber));
-					}
 				}
 
 				dev->nFreeChunks++;
+				
 			} else if (tags.chunkId > 0) {
 				/* chunkId > 0 so it is a data chunk... */
 				unsigned int endpos;