Commit d1b6ddcf authored by Ramon Nou's avatar Ramon Nou
Browse files

fix compressed order

parent d34e390c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Fixed
  - SYS_lstat does not exists on some architectures, change to newfstatat ([!269](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/269))
    - We cannot use lstat directly as may cause a recursion call on libc interception.
  - Un/Packing order of directory entries in compressed format was incorrect ([!281](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/281))
    

## [0.9.5] - 2025-08
### New
+5 −5
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@

  SPDX-License-Identifier: LGPL-3.0-or-later
*/

// clang-format off
#ifndef GKFS_CLIENT_FUSE_CONTEXT_HPP
#define GKFS_CLIENT_FUSE_CONTEXT_HPP

+30 −4
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@
#include <tuple>
#include <string>
#include <stdexcept>
#include <cstdint>
#include <cstring>
#include <type_traits>

namespace gkfs::rpc {
@@ -104,16 +106,40 @@ decompress_and_parse_entries(const OutputOrErr& out,
    std::vector<std::tuple<const std::string, bool, size_t, time_t>> entries;

    while(p < end) {
        bool is_dir = *reinterpret_cast<const bool*>(p);
        p += sizeof(bool);
        if(p + sizeof(uint8_t) > end) {
            LOG(ERROR, "{}() Unexpected end of buffer while parsing is_dir",
                __func__);
            break;
        }
        bool is_dir = (*reinterpret_cast<const uint8_t*>(p) != 0);
        p += sizeof(uint8_t);

        if(p + sizeof(size_t) > end) {
            LOG(ERROR, "{}() Unexpected end of buffer while parsing file_size",
                __func__);
            break;
        }
        size_t file_size = *reinterpret_cast<const size_t*>(p);
        p += sizeof(size_t);

        if(p + sizeof(time_t) > end) {
            LOG(ERROR, "{}() Unexpected end of buffer while parsing ctime",
                __func__);
            break;
        }
        time_t ctime = *reinterpret_cast<const time_t*>(p);
        p += sizeof(time_t);

        std::string name(p);
        p += name.length() + 1;
        // Name is null-terminated. We must check we don't go past 'end'.
        size_t name_len = strnlen(p, end - p);
        if(p + name_len >= end) {
            LOG(ERROR, "{}() Unexpected end of buffer while parsing name",
                __func__);
            break;
        }

        std::string name(p, name_len);
        p += name_len + 1;

        if(!name.empty()) {
            entries.emplace_back(name, is_dir, file_size, ctime);
+47 −10
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@
#include <iterator>
#include <algorithm>
#include <zstd.h>
#include <cstdint>
#include <cstring>


using namespace std;
@@ -246,11 +248,24 @@ decompress_and_parse_entries_standard(
    entries.reserve(out.dirents_size); // Approx

    while(p < end) {
        bool is_dir = (*p != 0);
        p += 1;
        if(p + sizeof(uint8_t) > end) {
            LOG(ERROR, "{}() Unexpected end of buffer while parsing is_dir",
                __func__);
            break;
        }
        bool is_dir = (*reinterpret_cast<const uint8_t*>(p) != 0);
        p += sizeof(uint8_t);

        // Name is null-terminated. We must check we don't go past 'end'.
        size_t name_len = strnlen(p, end - p);
        if(p + name_len >= end) {
            LOG(ERROR, "{}() Unexpected end of buffer while parsing name",
                __func__);
            break;
        }

        std::string name(p);
        p += name.length() + 1;
        std::string name(p, name_len);
        p += name_len + 1;

        if(!name.empty()) {
            entries.emplace_back(name, is_dir, 0, 0);
@@ -311,24 +326,46 @@ decompress_and_parse_entries_filtered(
        p = static_cast<const char*>(compressed_buffer);
        end = p + out.dirents_size;
    }

    std::vector<std::tuple<const std::string, bool, size_t, time_t>> entries;
    // We don't know exact count, but can optimize reserve?
    // entries.reserve(out.dirents_size / 32);

    while(p < end) {
        bool is_dir = (*p != 0);
        p += 1;

        std::string name(p);
        p += name.length() + 1;
        if(p + sizeof(uint8_t) > end) {
            LOG(ERROR, "{}() Unexpected end of buffer while parsing is_dir",
                __func__);
            break;
        }
        bool is_dir = (*reinterpret_cast<const uint8_t*>(p) != 0);
        p += sizeof(uint8_t);

        if(p + sizeof(size_t) > end) {
            LOG(ERROR, "{}() Unexpected end of buffer while parsing size",
                __func__);
            break;
        }
        size_t size = *reinterpret_cast<const size_t*>(p);
        p += sizeof(size_t);

        if(p + sizeof(time_t) > end) {
            LOG(ERROR, "{}() Unexpected end of buffer while parsing ctime",
                __func__);
            break;
        }
        time_t ctime = *reinterpret_cast<const time_t*>(p);
        p += sizeof(time_t);

        // Name is null-terminated. We must check we don't go past 'end'.
        size_t name_len = strnlen(p, end - p);
        if(p + name_len >= end) {
            LOG(ERROR, "{}() Unexpected end of buffer while parsing name",
                __func__);
            break;
        }

        std::string name(p, name_len);
        p += name_len + 1;

        if(!name.empty()) {
            entries.emplace_back(name, is_dir, size, ctime);
        }
+2 −2
Original line number Diff line number Diff line
@@ -580,8 +580,6 @@ RocksDBBackend::get_dirents_filtered_impl(const std::string& dir,
            eof = false;
            break;
        }
        scanned_count++;

        // Get File name
        auto name = it->key().ToString();
        // save as potential last key (full path for now, stripped later if
@@ -609,6 +607,8 @@ RocksDBBackend::get_dirents_filtered_impl(const std::string& dir,
            continue;
        }

        scanned_count++;

        Metadata md(it->value().ToString());
#ifdef HAS_RENAME
        // Remove entries with negative blocks (rename)
Loading