Repository: bitcoin/bitcoin
File: src/flatfile.cpp (C++)

Code before:
        return nullptr;
    }
    return file;
}

size_t FlatFileSeq::Allocate(const FlatFilePos& pos, size_t add_size, bool& out_of_space) const
{
    out_of_space = false;

    unsigned int n_old_chunks = (pos.nPos + m_chunk_size - 1) / m_chunk_size;
    unsigned int n_new_chunks = (pos.nPos + add_size + m_chunk_size - 1) / m_chunk_size;
    if (n_new_chunks > n_old_chunks) {
        size_t old_size = pos.nPos;
        size_t new_size = n_new_chunks * m_chunk_size;
        size_t inc_size = new_size - old_size;

        if (CheckDiskSpace(m_dir, inc_size)) {
            FILE *file = Open(pos);
            if (file) {
                LogDebug(BCLog::VALIDATION, "Pre-allocating up to position 0x%x in %s%05u.dat\n", new_size, m_prefix, pos.nFile);
                AllocateFileRange(file, pos.nPos, inc_size);
                fclose(file);
                return inc_size;
            }
        } else {
            out_of_space = true;
        }
    }
    return 0;
}

bool FlatFileSeq::Flush(const FlatFilePos& pos, bool finalize) const
{
    FILE* file = Open(FlatFilePos(pos.nFile, 0)); // Avoid fseek to nPos
    if (!file) {
        LogError("%s: failed to open file %d\n", __func__, pos.nFile);
        return false;
    }
    if (finalize && !TruncateFile(file, pos.nPos)) {
        fclose(file);
        LogError("%s: failed to truncate file %d\n", __func__, pos.nFile);
        return false;
    }
    if (!FileCommit(file)) {
        fclose(file);
        LogError("%s: failed to commit file %d\n", __func__, pos.nFile);
        return false;
    }
    DirectoryCommit(m_dir);

    fclose(file);

Review comment (bug):
Not sure how to handle this in the callers, probably something along these lines:
```diff
diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp
index 6b47a0fa0a..332e700995 100644
--- a/src/index/blockfilterindex.cpp
+++ b/src/index/blockfilterindex.cpp
@@ -227,10 +227,13 @@ size_t BlockFilterIndex::WriteFilterToDisk(FlatFilePos& pos, const BlockFilter&
 
     // Pre-allocate sufficient space for filter data.
     bool out_of_space;
-    m_filter_fileseq->Allocate(pos, data_size, out_of_space);
+    const size_t allocated_size = m_filter_fileseq->Allocate(pos, data_size, out_of_space);
     if (out_of_space) {
         LogPrintf("%s: out of disk space\n", __func__);
         return 0;
+    } else if (allocated_size < data_size) {
+        LogError("Failed to allocate %u for file %s.", data_size, pos.ToString());
+        return 0;
     }
 
     AutoFile fileout{m_filter_fileseq->Open(pos)};
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
index a344e13c89..3ff3aa9122 100644
--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -873,6 +873,9 @@ FlatFilePos BlockManager::FindNextBlockPos(unsigned int nAddSize, unsigned int n
     if (out_of_space) {
         m_opts.notifications.fatalError(_("Disk space is too low!"));
         return {};
+    } else if (bytes_allocated < nAddSize) {
+        m_opts.notifications.fatalError(_("Failed allocating disk space!"));
+        return {};
     }
     if (bytes_allocated != 0 && IsPruneMode()) {
         m_check_for_pruning = true;
@@ -918,6 +921,8 @@ bool BlockManager::FindUndoPos(BlockValidationState& state, int nFile, FlatFileP
     size_t bytes_allocated = m_undo_file_seq.Allocate(pos, nAddSize, out_of_space);
     if (out_of_space) {
         return FatalError(m_opts.notifications, state, _("Disk space is too low!"));
+    } else if (bytes_allocated < nAddSize) {
+        return FatalError(m_opts.notifications, state, _("Failed allocating disk space!"));
     }
     if (bytes_allocated != 0 && IsPruneMode()) {
         m_check_for_pruning = true;
```

Code after:
            LogError("Unable to close file %s", fs::PathToString(path));
        }
        return nullptr;
    }
    return file;
}

size_t FlatFileSeq::Allocate(const FlatFilePos& pos, size_t add_size, bool& out_of_space) const
{
    out_of_space = false;

    unsigned int n_old_chunks = (pos.nPos + m_chunk_size - 1) / m_chunk_size;
    unsigned int n_new_chunks = (pos.nPos + add_size + m_chunk_size - 1) / m_chunk_size;
    if (n_new_chunks > n_old_chunks) {
        size_t old_size = pos.nPos;
        size_t new_size = n_new_chunks * m_chunk_size;
        size_t inc_size = new_size - old_size;

        if (CheckDiskSpace(m_dir, inc_size)) {
            FILE *file = Open(pos);
            if (file) {
                LogDebug(BCLog::VALIDATION, "Pre-allocating up to position 0x%x in %s%05u.dat\n", new_size, m_prefix, pos.nFile);
                AllocateFileRange(file, pos.nPos, inc_size);
                if (fclose(file) != 0) {
                    LogError("Cannot close file %s%05u.dat after extending it with %u bytes", m_prefix, pos.nFile, new_size);
                    return 0;
                }
                return inc_size;
            }
        } else {
            out_of_space = true;
        }
    }
    return 0;
}

bool FlatFileSeq::Flush(const FlatFilePos& pos, bool finalize) const
{
    FILE* file = Open(FlatFilePos(pos.nFile, 0)); // Avoid fseek to nPos
    if (!file) {
        LogError("%s: failed to open file %d\n", __func__, pos.nFile);
        return false;
    }
    if (finalize && !TruncateFile(file, pos.nPos)) {
        LogError("%s: failed to truncate file %d\n", __func__, pos.nFile);
        if (fclose(file) != 0) {
            LogError("Failed to close file %d", pos.nFile);
        }
        return false;
    }
    if (!FileCommit(file)) {