Skip to content

Commit 992404b

Browse files
committed
validation: Refactor block file pre-allocation into FlatFileSeq.
1 parent e2d2abb commit 992404b

File tree

3 files changed

+53
-33
lines changed

3 files changed

+53
-33
lines changed

src/flatfile.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <flatfile.h>
88
#include <logging.h>
99
#include <tinyformat.h>
10+
#include <util/system.h>
1011

1112
FlatFileSeq::FlatFileSeq(fs::path dir, const char* prefix, size_t chunk_size) :
1213
m_dir(std::move(dir)),
@@ -45,3 +46,29 @@ FILE* FlatFileSeq::Open(const CDiskBlockPos& pos, bool fReadOnly)
4546
}
4647
return file;
4748
}
49+
50+
size_t FlatFileSeq::Allocate(const CDiskBlockPos& pos, size_t add_size, bool& out_of_space)
51+
{
52+
out_of_space = false;
53+
54+
unsigned int n_old_chunks = (pos.nPos + m_chunk_size - 1) / m_chunk_size;
55+
unsigned int n_new_chunks = (pos.nPos + add_size + m_chunk_size - 1) / m_chunk_size;
56+
if (n_new_chunks > n_old_chunks) {
57+
size_t old_size = pos.nPos;
58+
size_t new_size = n_new_chunks * m_chunk_size;
59+
size_t inc_size = new_size - old_size;
60+
61+
if (CheckDiskSpace(m_dir, inc_size)) {
62+
FILE *file = Open(pos);
63+
if (file) {
64+
LogPrintf("Pre-allocating up to position 0x%x in %s%05u.dat\n", new_size, m_prefix, pos.nFile);
65+
AllocateFileRange(file, pos.nPos, inc_size);
66+
fclose(file);
67+
return inc_size;
68+
}
69+
} else {
70+
out_of_space = true;
71+
}
72+
}
73+
return 0;
74+
}

src/flatfile.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ class FlatFileSeq
3434

3535
/** Open a handle to the file at the given position. */
3636
FILE* Open(const CDiskBlockPos& pos, bool fReadOnly = false);
37+
38+
/**
39+
* Allocate additional space in a file after the given starting position. The amount allocated
40+
* will be the minimum multiple of the sequence chunk size greater than add_size.
41+
*
42+
* @param[in] pos The starting position that bytes will be allocated after.
43+
* @param[in] add_size The minimum number of bytes to be allocated.
44+
* @param[out] out_of_space Whether the allocation failed due to insufficient disk space.
45+
* @return The number of bytes successfully allocated.
46+
*/
47+
size_t Allocate(const CDiskBlockPos& pos, size_t add_size, bool& out_of_space);
3748
};
3849

3950
#endif // BITCOIN_FLATFILE_H

src/validation.cpp

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,21 +3014,13 @@ static bool FindBlockPos(CDiskBlockPos &pos, unsigned int nAddSize, unsigned int
30143014
vinfoBlockFile[nFile].nSize += nAddSize;
30153015

30163016
if (!fKnown) {
3017-
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
3018-
unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
3019-
if (nNewChunks > nOldChunks) {
3020-
if (fPruneMode)
3021-
fCheckForPruning = true;
3022-
if (CheckDiskSpace(GetBlocksDir(), nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
3023-
FILE *file = OpenBlockFile(pos);
3024-
if (file) {
3025-
LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
3026-
AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
3027-
fclose(file);
3028-
}
3029-
}
3030-
else
3031-
return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
3017+
bool out_of_space;
3018+
size_t bytes_allocated = BlockFileSeq().Allocate(pos, nAddSize, out_of_space);
3019+
if (out_of_space) {
3020+
return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
3021+
}
3022+
if (bytes_allocated != 0 && fPruneMode) {
3023+
fCheckForPruning = true;
30323024
}
30333025
}
30343026

@@ -3042,27 +3034,17 @@ static bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos,
30423034

30433035
LOCK(cs_LastBlockFile);
30443036

3045-
unsigned int nNewSize;
30463037
pos.nPos = vinfoBlockFile[nFile].nUndoSize;
3047-
nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
3038+
vinfoBlockFile[nFile].nUndoSize += nAddSize;
30483039
setDirtyFileInfo.insert(nFile);
30493040

3050-
unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3051-
unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3052-
if (nNewChunks > nOldChunks) {
3053-
if (fPruneMode)
3054-
fCheckForPruning = true;
3055-
if (CheckDiskSpace(GetBlocksDir(), nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
3056-
FILE *file = OpenUndoFile(pos);
3057-
if (file) {
3058-
LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
3059-
AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
3060-
fclose(file);
3061-
}
3062-
}
3063-
else {
3064-
return AbortNode(state, "Disk space is low!", _("Error: Disk space is low!"));
3065-
}
3041+
bool out_of_space;
3042+
size_t bytes_allocated = UndoFileSeq().Allocate(pos, nAddSize, out_of_space);
3043+
if (out_of_space) {
3044+
return AbortNode(state, "Disk space is low!", _("Error: Disk space is low!"));
3045+
}
3046+
if (bytes_allocated != 0 && fPruneMode) {
3047+
fCheckForPruning = true;
30663048
}
30673049

30683050
return true;

0 commit comments

Comments
 (0)