]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd: use store-specific max_object_size for the OSD-layer write check 69018/head
authorKefu Chai <k.chai@proxmox.com>
Wed, 20 May 2026 07:55:58 +0000 (15:55 +0800)
committerKefu Chai <k.chai@proxmox.com>
Wed, 20 May 2026 11:59:38 +0000 (19:59 +0800)
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 <k.chai@proxmox.com>
src/crimson/os/futurized_store.h
src/crimson/os/seastore/seastore.h
src/crimson/osd/pg_backend.cc
src/crimson/osd/pg_backend.h

index b8e11de515ffc1aae5a6c8d669dfd8305a09bcd5..8ca18388427c6b1493ba15b2136953cdb424d469 100644 (file)
@@ -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:
index 029f2216554e6363302a48fb5251fc5d3c86b297..701d68e00845140e22dc4876d6c4fc9db9004585 100644 (file)
@@ -185,6 +185,12 @@ public:
       return 256;
     }
 
+    uint64_t get_max_object_size() const override final {
+      return std::min<uint64_t>(
+        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
index d0c9ff412d5f9d5aa516189131a607eded11a5c5..b8b4236d69102f89f4ec9c11c29859f7ecd8d9c1 100644 (file)
@@ -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;
index bda7d73ac1b9059b4676d907a12cdd68192c6053..2859b9a54cf6465f8c799ee413b42920e74cd560 100644 (file)
@@ -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<ceph::bufferlist> _read(
     const hobject_t& hoid,
     size_t object_size,