Commit 3d7b0945 authored by Ramon Nou's avatar Ramon Nou
Browse files

Use direct 2 GiB storage calibration probe

parent cd76bc08
Loading
Loading
Loading
Loading
Loading
+51 −14
Changes for src/daemon/util.cpp: 51 added lines, 14 removed lines.
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
#include <chrono>     // Added for sleep (if needed)
#include <cstring>
#include <fstream>
#include <fcntl.h>
#include <iostream>
#include <limits>
#include <cmath>
@@ -108,35 +109,67 @@ benchmark_storage(const std::filesystem::path& root, int seconds) {
    if(!gkfs::env::get_var_bool(gkfs::env::RANDOM_SLICING_CALIBRATION, false))
        return {true, 100.0f, 1.0f};
    const auto path = root / ".gkfs_rs_calibration";
    constexpr std::size_t block_size = 1024 * 1024;
    constexpr std::size_t probe_size = 2ULL * 1024ULL * 1024ULL * 1024ULL;
    constexpr std::size_t alignment = 4096;
    int fd = -1;
    void* buffer = nullptr;
    try {
        std::vector<char> buffer(1024 * 1024, 'x');
        std::filesystem::create_directories(root);
        std::ofstream out(path, std::ios::binary | std::ios::trunc);
        if(!out)
        fd = ::open(path.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_DIRECT,
                    0600);
        if(fd < 0)
            return {false, 0.0f, 1.0f};
        if(::posix_memalign(&buffer, alignment, block_size) != 0) {
            ::close(fd);
            fd = -1;
            return {false, 0.0f, 1.0f};
        }
        std::memset(buffer, 'x', block_size);
        const auto start = std::chrono::steady_clock::now();
        const auto deadline = start + std::chrono::seconds(seconds);
        constexpr std::size_t probe_size = 64 * 1024 * 1024;
        std::size_t written = 0;
        std::size_t position = 0;
        while(std::chrono::steady_clock::now() < deadline) {
            const auto count = buffer.size();
            if(position + count > probe_size) {
                out.seekp(0);
            if(position + block_size > probe_size) {
                if(::fdatasync(fd) != 0) {
                    ::free(buffer);
                    buffer = nullptr;
                    ::close(fd);
                    fd = -1;
                    std::error_code ec;
                    std::filesystem::remove(path, ec);
                    return {false, 0.0f, 1.0f};
                }
                position = 0;
            }
            out.write(buffer.data(), static_cast<std::streamsize>(count));
            if(!out) {
                out.close();
            const auto ret = ::pwrite(fd, buffer, block_size,
                                      static_cast<off_t>(position));
            if(ret != static_cast<ssize_t>(block_size)) {
                ::free(buffer);
                buffer = nullptr;
                ::close(fd);
                fd = -1;
                std::error_code ec;
                std::filesystem::remove(path, ec);
                return {false, 0.0f, 1.0f};
            }
            written += count;
            position += count;
            written += static_cast<std::size_t>(ret);
            position += static_cast<std::size_t>(ret);
        }
        if(::fdatasync(fd) != 0) {
            ::free(buffer);
            buffer = nullptr;
            ::close(fd);
            fd = -1;
            std::error_code ec;
            std::filesystem::remove(path, ec);
            return {false, 0.0f, 1.0f};
        }
        out.flush();
        out.close();
        ::free(buffer);
        buffer = nullptr;
        ::close(fd);
        fd = -1;
        const auto elapsed = std::chrono::duration<double>(
                                     std::chrono::steady_clock::now() - start)
                                     .count();
@@ -149,6 +182,10 @@ benchmark_storage(const std::filesystem::path& root, int seconds) {
        return {true, static_cast<float>(mbps),
                static_cast<float>(std::clamp(mbps / 100.0, 0.05, 20.0))};
    } catch(const std::exception&) {
        if(buffer != nullptr)
            ::free(buffer);
        if(fd >= 0)
            ::close(fd);
        std::error_code ec;
        std::filesystem::remove(path, ec);
        return {false, 0.0f, 1.0f};