aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init.cpp53
-rw-r--r--src/main.cpp4
2 files changed, 38 insertions, 19 deletions
diff --git a/src/init.cpp b/src/init.cpp
index bd9d38619f..f911dbd2d1 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -473,24 +473,43 @@ struct CImportingNow
// If we're using -prune with -reindex, then delete block files that will be ignored by the
// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
-// is missing, and since pruning works by deleting the oldest block file first, just check
-// for block file 0, and if it doesn't exist, delete all the block files in the
-// directory (since they won't be read by the reindex but will take up disk space).
-void DeleteAllBlockFiles()
+// is missing, do the same here to delete any later block files after a gap. Also delete all
+// rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile
+// is in sync with what's actually on disk by the time we start downloading, so that pruning
+// works correctly.
+void CleanupBlockRevFiles()
{
- if (boost::filesystem::exists(GetBlockPosFilename(CDiskBlockPos(0, 0), "blk")))
- return;
+ using namespace boost::filesystem;
+ map<string, path> mapBlockFiles;
+
+ // Glob all blk?????.dat and rev?????.dat files from the blocks directory.
+ // Remove the rev files immediately and insert the blk file paths into an
+ // ordered map keyed by block file index.
+ LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
+ path blocksdir = GetDataDir() / "blocks";
+ for (directory_iterator it(blocksdir); it != directory_iterator(); it++) {
+ if (is_regular_file(*it) &&
+ it->path().filename().string().length() == 12 &&
+ it->path().filename().string().substr(8,4) == ".dat")
+ {
+ if (it->path().filename().string().substr(0,3) == "blk")
+ mapBlockFiles[it->path().filename().string().substr(3,5)] = it->path();
+ else if (it->path().filename().string().substr(0,3) == "rev")
+ remove(it->path());
+ }
+ }
- LogPrintf("Removing all blk?????.dat and rev?????.dat files for -reindex with -prune\n");
- boost::filesystem::path blocksdir = GetDataDir() / "blocks";
- for (boost::filesystem::directory_iterator it(blocksdir); it != boost::filesystem::directory_iterator(); it++) {
- if (is_regular_file(*it)) {
- if ((it->path().filename().string().length() == 12) &&
- (it->path().filename().string().substr(8,4) == ".dat") &&
- ((it->path().filename().string().substr(0,3) == "blk") ||
- (it->path().filename().string().substr(0,3) == "rev")))
- boost::filesystem::remove(it->path());
+ // Remove all block files that aren't part of a contiguous set starting at
+ // zero by walking the ordered map (keys are block file indices) by
+ // keeping a separate counter. Once we hit a gap (or if 0 doesn't exist)
+ // start removing block files.
+ int nContigCounter = 0;
+ BOOST_FOREACH(const PAIRTYPE(string, path)& item, mapBlockFiles) {
+ if (atoi(item.first) == nContigCounter) {
+ nContigCounter++;
+ continue;
}
+ remove(item.second);
}
}
@@ -1110,9 +1129,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (fReindex) {
pblocktree->WriteReindexing(true);
- //If we're reindexing in prune mode, wipe away all our block and undo data files
+ //If we're reindexing in prune mode, wipe away unusable block files and all undo data files
if (fPruneMode)
- DeleteAllBlockFiles();
+ CleanupBlockRevFiles();
}
if (!LoadBlockIndex()) {
diff --git a/src/main.cpp b/src/main.cpp
index 6cabe80242..05e5ca4234 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3040,9 +3040,9 @@ void FindFilesToPrune(std::set<int>& setFilesToPrune)
if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
break;
- // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip
+ // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
- break;
+ continue;
PruneOneBlockFile(fileNumber);
// Queue up the files for removal