Mercurial > yaffs-ecoscentric-gpl
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 |
