Loading CHANGELOG.md +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading include/client/fuse/fuse_client.hpp +5 −5 Original line number Diff line number Diff line Loading @@ -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 Loading include/client/rpc/utils.hpp +30 −4 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ #include <tuple> #include <string> #include <stdexcept> #include <cstdint> #include <cstring> #include <type_traits> namespace gkfs::rpc { Loading Loading @@ -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); Loading src/client/rpc/forward_metadata.cpp +47 −10 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ #include <iterator> #include <algorithm> #include <zstd.h> #include <cstdint> #include <cstring> using namespace std; Loading Loading @@ -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); Loading Loading @@ -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); } Loading src/daemon/backend/metadata/rocksdb_backend.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading
CHANGELOG.md +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
include/client/fuse/fuse_client.hpp +5 −5 Original line number Diff line number Diff line Loading @@ -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 Loading
include/client/rpc/utils.hpp +30 −4 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ #include <tuple> #include <string> #include <stdexcept> #include <cstdint> #include <cstring> #include <type_traits> namespace gkfs::rpc { Loading Loading @@ -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); Loading
src/client/rpc/forward_metadata.cpp +47 −10 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ #include <iterator> #include <algorithm> #include <zstd.h> #include <cstdint> #include <cstring> using namespace std; Loading Loading @@ -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); Loading Loading @@ -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); } Loading
src/daemon/backend/metadata/rocksdb_backend.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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