comparison yaffs_guts.c @ 383:b9e2ee9e8f28

Faster block iteration where all blocks are being checked
author charles <charles>
date Fri, 12 Mar 2010 02:48:34 +0000
parents f85ba1a6e018
children 36569f389824
comparison
equal deleted inserted replaced
382:f85ba1a6e018 383:b9e2ee9e8f28
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14 const char *yaffs_guts_c_version = 14 const char *yaffs_guts_c_version =
15 "$Id: yaffs_guts.c,v 1.118 2010-03-12 01:22:48 charles Exp $"; 15 "$Id: yaffs_guts.c,v 1.119 2010-03-12 02:48:34 charles Exp $";
16 16
17 #include "yportenv.h" 17 #include "yportenv.h"
18 #include "yaffs_trace.h" 18 #include "yaffs_trace.h"
19 19
20 #include "yaffsinterface.h" 20 #include "yaffsinterface.h"
1060 */ 1060 */
1061 static int yaffs_CalcOldestDirtySequence(yaffs_Device *dev) 1061 static int yaffs_CalcOldestDirtySequence(yaffs_Device *dev)
1062 { 1062 {
1063 int i; 1063 int i;
1064 __u32 seq; 1064 __u32 seq;
1065 yaffs_BlockInfo *b = 0; 1065 yaffs_BlockInfo *b;
1066 1066
1067 if(!dev->param.isYaffs2) 1067 if(!dev->param.isYaffs2)
1068 return 0; 1068 return 0;
1069 1069
1070 /* Find the oldest dirty sequence number. */ 1070 /* Find the oldest dirty sequence number. */
1071 seq = dev->sequenceNumber; 1071 seq = dev->sequenceNumber;
1072 b = dev->blockInfo;
1072 for (i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) { 1073 for (i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
1073 b = yaffs_GetBlockInfo(dev, i);
1074 if (b->blockState == YAFFS_BLOCK_STATE_FULL && 1074 if (b->blockState == YAFFS_BLOCK_STATE_FULL &&
1075 (b->pagesInUse - b->softDeletions) < dev->param.nChunksPerBlock && 1075 (b->pagesInUse - b->softDeletions) < dev->param.nChunksPerBlock &&
1076 b->sequenceNumber < seq) 1076 b->sequenceNumber < seq)
1077 seq = b->sequenceNumber; 1077 seq = b->sequenceNumber;
1078 b++;
1078 } 1079 }
1079 return seq; 1080 return seq;
1080 } 1081 }
1081 1082
1082 1083
2798 * We'll do a refresh this time around.... 2799 * We'll do a refresh this time around....
2799 * Update the refresh skip and find the oldest block. 2800 * Update the refresh skip and find the oldest block.
2800 */ 2801 */
2801 dev->refreshSkip = dev->param.refreshPeriod; 2802 dev->refreshSkip = dev->param.refreshPeriod;
2802 dev->refreshCount++; 2803 dev->refreshCount++;
2803 2804 bi = dev->blockInfo;
2804 for (b = dev->internalStartBlock; b <=dev->internalEndBlock; b++){ 2805 for (b = dev->internalStartBlock; b <=dev->internalEndBlock; b++){
2805
2806 bi = yaffs_GetBlockInfo(dev, b);
2807
2808 2806
2809 if (bi->blockState == YAFFS_BLOCK_STATE_FULL){ 2807 if (bi->blockState == YAFFS_BLOCK_STATE_FULL){
2810 2808
2811 if(oldest < 1 || 2809 if(oldest < 1 ||
2812 bi->sequenceNumber < oldestSequence){ 2810 bi->sequenceNumber < oldestSequence){
2813 oldest = b; 2811 oldest = b;
2814 oldestSequence = bi->sequenceNumber; 2812 oldestSequence = bi->sequenceNumber;
2815 } 2813 }
2816 } 2814 }
2815 bi++;
2817 } 2816 }
2818 2817
2819 if (oldest > 0) { 2818 if (oldest > 0) {
2820 T(YAFFS_TRACE_GC, 2819 T(YAFFS_TRACE_GC,
2821 (TSTR("GC refresh count %d selected block %d with sequenceNumber %d" TENDSTR), 2820 (TSTR("GC refresh count %d selected block %d with sequenceNumber %d" TENDSTR),
2843 yaffs_BlockInfo *bi; 2842 yaffs_BlockInfo *bi;
2844 int pendingPrioritisedExist = 0; 2843 int pendingPrioritisedExist = 0;
2845 2844
2846 /* First let's see if we need to grab a prioritised block */ 2845 /* First let's see if we need to grab a prioritised block */
2847 if (dev->hasPendingPrioritisedGCs) { 2846 if (dev->hasPendingPrioritisedGCs) {
2847 bi = dev->blockInfo;
2848 for (i = dev->internalStartBlock; i < dev->internalEndBlock && !prioritised; i++) { 2848 for (i = dev->internalStartBlock; i < dev->internalEndBlock && !prioritised; i++) {
2849
2850 bi = yaffs_GetBlockInfo(dev, i);
2851 /* yaffs_VerifyBlock(dev,bi,i); */
2852 2849
2853 if (bi->gcPrioritise) { 2850 if (bi->gcPrioritise) {
2854 pendingPrioritisedExist = 1; 2851 pendingPrioritisedExist = 1;
2855 if (bi->blockState == YAFFS_BLOCK_STATE_FULL && 2852 if (bi->blockState == YAFFS_BLOCK_STATE_FULL &&
2856 yaffs_BlockNotDisqualifiedFromGC(dev, bi)) { 2853 yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
2858 dirtiest = i; 2855 dirtiest = i;
2859 prioritised = 1; 2856 prioritised = 1;
2860 aggressive = 1; /* Fool the non-aggressive skip logiv below */ 2857 aggressive = 1; /* Fool the non-aggressive skip logiv below */
2861 } 2858 }
2862 } 2859 }
2860 bi++;
2863 } 2861 }
2864 2862
2865 if (!pendingPrioritisedExist) /* None found, so we can clear this */ 2863 if (!pendingPrioritisedExist) /* None found, so we can clear this */
2866 dev->hasPendingPrioritisedGCs = 0; 2864 dev->hasPendingPrioritisedGCs = 0;
2867 } 2865 }
5968 chunkData = yaffs_GetTempBuffer(dev, __LINE__); 5966 chunkData = yaffs_GetTempBuffer(dev, __LINE__);
5969 5967
5970 dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER; 5968 dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;
5971 5969
5972 /* Scan all the blocks to determine their state */ 5970 /* Scan all the blocks to determine their state */
5971 bi = dev->blockInfo;
5973 for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) { 5972 for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) {
5974 bi = yaffs_GetBlockInfo(dev, blk);
5975 yaffs_ClearChunkBits(dev, blk); 5973 yaffs_ClearChunkBits(dev, blk);
5976 bi->pagesInUse = 0; 5974 bi->pagesInUse = 0;
5977 bi->softDeletions = 0; 5975 bi->softDeletions = 0;
5978 5976
5979 yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber); 5977 yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber);
5995 T(YAFFS_TRACE_SCAN_DEBUG, 5993 T(YAFFS_TRACE_SCAN_DEBUG,
5996 (TSTR("Block empty " TENDSTR))); 5994 (TSTR("Block empty " TENDSTR)));
5997 dev->nErasedBlocks++; 5995 dev->nErasedBlocks++;
5998 dev->nFreeChunks += dev->param.nChunksPerBlock; 5996 dev->nFreeChunks += dev->param.nChunksPerBlock;
5999 } 5997 }
5998 bi++;
6000 } 5999 }
6001 6000
6002 startIterator = dev->internalStartBlock; 6001 startIterator = dev->internalStartBlock;
6003 endIterator = dev->internalEndBlock; 6002 endIterator = dev->internalEndBlock;
6004 6003
6492 dev->blocksInCheckpoint = 0; 6491 dev->blocksInCheckpoint = 0;
6493 6492
6494 chunkData = yaffs_GetTempBuffer(dev, __LINE__); 6493 chunkData = yaffs_GetTempBuffer(dev, __LINE__);
6495 6494
6496 /* Scan all the blocks to determine their state */ 6495 /* Scan all the blocks to determine their state */
6496 bi = dev->blockInfo;
6497 for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) { 6497 for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) {
6498 bi = yaffs_GetBlockInfo(dev, blk);
6499 yaffs_ClearChunkBits(dev, blk); 6498 yaffs_ClearChunkBits(dev, blk);
6500 bi->pagesInUse = 0; 6499 bi->pagesInUse = 0;
6501 bi->softDeletions = 0; 6500 bi->softDeletions = 0;
6502 6501
6503 yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber); 6502 yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber);
6546 ("Block scanning block %d has bad sequence number %d" 6545 ("Block scanning block %d has bad sequence number %d"
6547 TENDSTR), blk, sequenceNumber)); 6546 TENDSTR), blk, sequenceNumber));
6548 6547
6549 } 6548 }
6550 } 6549 }
6550 bi++;
6551 } 6551 }
6552 6552
6553 T(YAFFS_TRACE_SCAN, 6553 T(YAFFS_TRACE_SCAN,
6554 (TSTR("%d blocks to be sorted..." TENDSTR), nBlocksToScan)); 6554 (TSTR("%d blocks to be sorted..." TENDSTR), nBlocksToScan));
6555 6555
7992 } 7992 }
7993 } 7993 }
7994 7994
7995 static int yaffs_CountFreeChunks(yaffs_Device *dev) 7995 static int yaffs_CountFreeChunks(yaffs_Device *dev)
7996 { 7996 {
7997 int nFree; 7997 int nFree=0;
7998 int b; 7998 int b;
7999 7999
8000 yaffs_BlockInfo *blk; 8000 yaffs_BlockInfo *blk;
8001 8001
8002 for (nFree = 0, b = dev->internalStartBlock; b <= dev->internalEndBlock; 8002 blk = dev->blockInfo;
8003 b++) { 8003 for (b = dev->internalStartBlock; b <= dev->internalEndBlock; b++) {
8004 blk = yaffs_GetBlockInfo(dev, b);
8005
8006 switch (blk->blockState) { 8004 switch (blk->blockState) {
8007 case YAFFS_BLOCK_STATE_EMPTY: 8005 case YAFFS_BLOCK_STATE_EMPTY:
8008 case YAFFS_BLOCK_STATE_ALLOCATING: 8006 case YAFFS_BLOCK_STATE_ALLOCATING:
8009 case YAFFS_BLOCK_STATE_COLLECTING: 8007 case YAFFS_BLOCK_STATE_COLLECTING:
8010 case YAFFS_BLOCK_STATE_FULL: 8008 case YAFFS_BLOCK_STATE_FULL:
8013 blk->softDeletions); 8011 blk->softDeletions);
8014 break; 8012 break;
8015 default: 8013 default:
8016 break; 8014 break;
8017 } 8015 }
8016 blk++;
8018 } 8017 }
8019 8018
8020 return nFree; 8019 return nFree;
8021 } 8020 }
8022 8021