From 9f8642bbd63bfaf4b4e3599692dab6bd9cbc73f6 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Wed, 20 May 2026 15:55:58 +0800 Subject: [PATCH] crimson/osd: use store-specific max_object_size for the OSD-layer write check is_offset_and_length_valid() checked write sizes against osd_max_object_size (128 MiB), but SeaStore caps per-onode laddr space at seastore_default_max_object_size (16 MiB). Writes between the two limits pass the OSD check, reach SeaStore, and trip prepare_data_reservation()'s ceph_assert(), crashing the OSD and its replicas. Add FuturizedStore::Shard::get_max_object_size() (returns osd_max_object_size by default) and override it in SeaStore::Shard to return min(osd_max_object_size, max_object_size). Convert is_offset_and_length_valid() from a static function to a PGBackend member that queries the store, so EFBIG reaches the client before the write ever hits the store. Signed-off-by: Kefu Chai --- src/crimson/os/futurized_store.h | 5 +++++ src/crimson/os/seastore/seastore.h | 6 ++++++ src/crimson/osd/pg_backend.cc | 9 +++++---- src/crimson/osd/pg_backend.h | 3 +++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/crimson/os/futurized_store.h b/src/crimson/os/futurized_store.h index b8e11de515f..8ca18388427 100644 --- a/src/crimson/os/futurized_store.h +++ b/src/crimson/os/futurized_store.h @@ -207,6 +207,11 @@ public: uint32_t op_flags = 0) = 0; virtual unsigned get_max_attr_name_length() const = 0; + + /// Override to report a tighter per-object cap than osd_max_object_size. + virtual uint64_t get_max_object_size() const { + return crimson::common::local_conf()->osd_max_object_size; + } }; public: diff --git a/src/crimson/os/seastore/seastore.h b/src/crimson/os/seastore/seastore.h index 029f2216554..701d68e0084 100644 --- a/src/crimson/os/seastore/seastore.h +++ b/src/crimson/os/seastore/seastore.h @@ -185,6 +185,12 @@ public: return 256; } + uint64_t get_max_object_size() const override final { + return std::min( + crimson::common::local_conf()->osd_max_object_size, + max_object_size); + } + omap_root_t select_log_omap_root(Onode& onode) const; // only exposed to SeaStore diff --git a/src/crimson/osd/pg_backend.cc b/src/crimson/osd/pg_backend.cc index d0c9ff412d5..b8b4236d691 100644 --- a/src/crimson/osd/pg_backend.cc +++ b/src/crimson/osd/pg_backend.cc @@ -613,13 +613,14 @@ void PGBackend::truncate_update_size_and_usage(object_stat_sum_t& delta_stats, } } -static bool is_offset_and_length_valid( +bool PGBackend::is_offset_and_length_valid( const std::uint64_t offset, - const std::uint64_t length) + const std::uint64_t length) const { - if (const std::uint64_t max = local_conf()->osd_max_object_size; + if (const std::uint64_t max = + store.f_store.get_sharded_store(store.store_index).get_max_object_size(); offset >= max || length > max || offset + length > max) { - logger().debug("{} osd_max_object_size: {}, offset: {}, len: {}; " + logger().debug("{} max_object_size: {}, offset: {}, len: {}; " "Hard limit of object size is 4GB", __func__, max, offset, length); return false; diff --git a/src/crimson/osd/pg_backend.h b/src/crimson/osd/pg_backend.h index bda7d73ac1b..2859b9a54cf 100644 --- a/src/crimson/osd/pg_backend.h +++ b/src/crimson/osd/pg_backend.h @@ -470,6 +470,9 @@ public: const hobject_t &oid); private: + bool is_offset_and_length_valid( + std::uint64_t offset, std::uint64_t length) const; + virtual ll_read_ierrorator::future _read( const hobject_t& hoid, size_t object_size, -- 2.47.3