diff options
-rw-r--r-- | src/init.cpp | 4 | ||||
-rw-r--r-- | src/util/system.cpp | 8 | ||||
-rw-r--r-- | src/util/system.h | 1 | ||||
-rw-r--r-- | src/validation.cpp | 32 | ||||
-rw-r--r-- | src/validation.h | 5 |
5 files changed, 23 insertions, 27 deletions
diff --git a/src/init.cpp b/src/init.cpp index 8b831a726f..5111baddd2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1675,11 +1675,11 @@ bool AppInitMain(InitInterfaces& interfaces) // ********************************************************* Step 11: import blocks - if (!CheckDiskSpace(/* additional_bytes */ 0, /* blocks_dir */ false)) { + if (!CheckDiskSpace(GetDataDir())) { InitError(strprintf(_("Error: Disk space is low for %s"), GetDataDir())); return false; } - if (!CheckDiskSpace(/* additional_bytes */ 0, /* blocks_dir */ true)) { + if (!CheckDiskSpace(GetBlocksDir())) { InitError(strprintf(_("Error: Disk space is low for %s"), GetBlocksDir())); return false; } diff --git a/src/util/system.cpp b/src/util/system.cpp index 6e82de743a..3e6c2ae5d4 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -135,6 +135,14 @@ bool DirIsWritable(const fs::path& directory) return true; } +bool CheckDiskSpace(const fs::path& dir, uint64_t nAdditionalBytes) +{ + constexpr uint64_t nMinDiskSpace = 52428800; // 50 MiB + + uint64_t nFreeBytesAvailable = fs::space(dir).available; + return nFreeBytesAvailable >= nMinDiskSpace + nAdditionalBytes; +} + /** * Interpret a string argument as a boolean. * diff --git a/src/util/system.h b/src/util/system.h index 69ae11d1ed..2a2ee9bc1d 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -72,6 +72,7 @@ bool RenameOver(fs::path src, fs::path dest); bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false); void UnlockDirectory(const fs::path& directory, const std::string& lockfile_name); bool DirIsWritable(const fs::path& directory); +bool CheckDiskSpace(const fs::path& dir, uint64_t nAdditionalBytes = 0); /** Release all directory locks. This is used for unit testing only, at runtime * the global destructor will take care of the locks. diff --git a/src/validation.cpp b/src/validation.cpp index 1806bc1268..06e0e99290 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2134,8 +2134,9 @@ bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState & // Write blocks and block index to disk. if (fDoFullFlush || fPeriodicWrite) { // Depend on nMinDiskSpace to ensure we can write block index - if (!CheckDiskSpace(0, true)) - return state.Error("out of disk space"); + if (!CheckDiskSpace(GetBlocksDir())) { + return AbortNode(state, "Disk space is low!", _("Error: Disk space is low!")); + } // First make sure all block and undo data is flushed to disk. FlushBlockFile(); // Then update all block file information (which may refer to block and undo files). @@ -2168,8 +2169,9 @@ bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState & // twice (once in the log, and once in the tables). This is already // an overestimation, as most will delete an existing entry or // overwrite one. Still, use a conservative safety factor of 2. - if (!CheckDiskSpace(48 * 2 * 2 * pcoinsTip->GetCacheSize())) - return state.Error("out of disk space"); + if (!CheckDiskSpace(GetDataDir(), 48 * 2 * 2 * pcoinsTip->GetCacheSize())) { + return AbortNode(state, "Disk space is low!", _("Error: Disk space is low!")); + } // Flush the chainstate (which may refer to block index entries). if (!pcoinsTip->Flush()) return AbortNode(state, "Failed to write to coin database"); @@ -3014,7 +3016,7 @@ static bool FindBlockPos(CDiskBlockPos &pos, unsigned int nAddSize, unsigned int if (nNewChunks > nOldChunks) { if (fPruneMode) fCheckForPruning = true; - if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos, true)) { + if (CheckDiskSpace(GetBlocksDir(), nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) { FILE *file = OpenBlockFile(pos); if (file) { LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile); @@ -3023,7 +3025,7 @@ static bool FindBlockPos(CDiskBlockPos &pos, unsigned int nAddSize, unsigned int } } else - return error("out of disk space"); + return AbortNode("Disk space is low!", _("Error: Disk space is low!")); } } @@ -3047,7 +3049,7 @@ static bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, if (nNewChunks > nOldChunks) { if (fPruneMode) fCheckForPruning = true; - if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos, true)) { + if (CheckDiskSpace(GetBlocksDir(), nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) { FILE *file = OpenUndoFile(pos); if (file) { LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile); @@ -3055,8 +3057,9 @@ static bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, fclose(file); } } - else - return state.Error("out of disk space"); + else { + return AbortNode(state, "Disk space is low!", _("Error: Disk space is low!")); + } } return true; @@ -3763,17 +3766,6 @@ static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfte nLastBlockWeCanPrune, count); } -bool CheckDiskSpace(uint64_t nAdditionalBytes, bool blocks_dir) -{ - uint64_t nFreeBytesAvailable = fs::space(blocks_dir ? GetBlocksDir() : GetDataDir()).available; - - // Check for nMinDiskSpace bytes (currently 50MB) - if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) - return AbortNode("Disk space is low!", _("Error: Disk space is low!")); - - return true; -} - static FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly) { if (pos.IsNull()) diff --git a/src/validation.h b/src/validation.h index 1975846b69..1beee7869f 100644 --- a/src/validation.h +++ b/src/validation.h @@ -181,9 +181,6 @@ extern arith_uint256 nMinimumChainWork; /** Best header we've seen so far (used for getheaders queries' starting points). */ extern CBlockIndex *pindexBestHeader; -/** Minimum disk space required - used in CheckDiskSpace() */ -static const uint64_t nMinDiskSpace = 52428800; - /** Pruning-related variables and constants */ /** True if any block files have ever been pruned. */ extern bool fHavePruned; @@ -245,8 +242,6 @@ bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<cons */ bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, CValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr, CBlockHeader* first_invalid = nullptr) LOCKS_EXCLUDED(cs_main); -/** Check whether enough disk space is available for an incoming block */ -bool CheckDiskSpace(uint64_t nAdditionalBytes = 0, bool blocks_dir = false); /** Open a block file (blk?????.dat) */ FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly = false); /** Translation to a filesystem path */ |