OK, thanks a lot. Hugo Charles Manning escribió: > On Thursday 18 March 2010 04:50:56 Hugo Etchegoyen wrote: > >> Charles, >> >> As I said in a previous mail, I was looking for means of speeding up >> yaffs shutdown during power fail, and that included disabling GC. Your >> last modification (the yaffs_gc_control parameter) addresses that issue. >> >> However, although setting this flag to zero will prevent entering GC, it >> will not abort a currently active GC. I had originally proposed to >> decrease the value of maxCopies in GarbageCollectBlock() to make it >> finer grained, but it looks faster and safer to just check your flag in >> each iteration of the copying loop: >> >> for (/* init already done */; >> retVal == YAFFS_OK && >> dev->gcChunk < dev->param.nChunksPerBlock && >> (bi->blockState == YAFFS_BLOCK_STATE_COLLECTING) && >> maxCopies > 0; >> dev->gcChunk++, oldChunk++) { >> >> if(dev->param.gcControl && >> (dev->param.gcControl(dev) & 1) == 0) >> break; >> >> if (yaffs_CheckChunkBit(dev, block, dev->gcChunk)) { >> >> /* This page is in use and might need to be copied off */ >> ... >> > > Doing that should be fine. It should be OK to interrupt gc at any page. That's > pretty much what the maxCopy stuff is doing anyway. > > I would tend to push the gcControl check into the for(). > > > > > >> As yaffs may now be shut down disabling GC, and depending on how much >> data is written with GC disabled (less than a block size in my case), >> maybe at initialization time there might be less free blocks than >> advisable. So I thought that it might be useful to catch up with delayed >> GCs at the end of yaffs_GutsInitialise(). Do you think this is >> necessary/advisable? >> > > I don't think it is necessary. > > >> Would this code handle that correctly? >> >> /* Clean up any aborted checkpoint data */ >> if(!dev->isCheckpointed && dev->blocksInCheckpoint > 0) >> yaffs_InvalidateCheckpoint(dev); >> >> > > > >> /* Honor any pending GCs */ >> do { >> x = dev->nErasedBlocks; >> yaffs_CheckGarbageCollection(dev); >> } while ( dev->gcBlock > 0 || x < dev->nErasedBlocks ); >> >> > > There is no need to resume any gc per se. yaffs_CheckGarbageCollection() > already does iteration. > > If you do it here then the checkpoint will be immediately invalidated which is > perhaps not a good idea. You might as well just leave this to be sorted out > on the first write. > > > >> T(YAFFS_TRACE_TRACING, >> (TSTR("yaffs: yaffs_GutsInitialise() done.\n" TENDSTR))); >> >> return YAFFS_OK; >> >> I also noticed that there is a possible source of delay when updating >> dirty directories, since once started it will iterate over a list of >> pending updates with the yaffs lock taken. I propose adding another >> flag, yaffs_udd_control ("udd" for Update Dirty Directories) and the >> corresponding callback (dev->uddControl). Then >> yaffs_UpdateDirtyDirectories() can check this flag in each iteration of >> the updating loop: >> >> while(!ylist_empty(&dev->dirtyDirectories)){ >> >> if(dev->param.uddControl && >> (dev->param.uddControl(dev) & 1) == 0) >> break; >> >> link = dev->dirtyDirectories.next; >> ylist_del_init(link); >> ... >> > > That should be fine to do, > I'll be adding flags like these when I flesh out the background task with > background garbage collection etc. > > >> Please advise if these modifications are OK. I have attached the >> modified files (yaffs_guts.h, yaffs_guts.c and yaffs_fs.c). I have >> compiled and tried the module and it seems to work properly, including >> disabling GC and UDD, writing some data, then enabling them again and >> writing some more. I haven't yet simulated a power fail situation when >> one would abort an ongoing GC or UDD, then write some data, sync and >> unmount. I'll report back as soon as I can try that. >> >> Best regards, >> Hugo >> > > > > > -- Ing. Hugo Eduardo Etchegoyen* *Gerente Dto. Software de Base Compañía Hasar | Grupo Hasar* *Marcos Sastre y José Ingenieros El Talar. Pacheco [B1618CSD] Buenos Aires. Argentina Tel [54 11] 4117 8900 | Fax [54 11] 4117 8998 E-mail: hetchegoyen@hasar.com Visítenos en: www.hasar.com Información legal y política de confidencialidad: www.grupohasar.com/disclaimer