From: Kefu Chai Date: Wed, 20 May 2026 07:36:51 +0000 (+0800) Subject: crimson/seastore: reject oversized writes and zeros instead of aborting X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b83a20a2fc28a8cf1c7bfbff799e14b583634c89;p=ceph.git crimson/seastore: reject oversized writes and zeros instead of aborting prepare_data_reservation() ceph_assert()s the request fits within seastore_default_max_object_size (16 MiB), but the OSD validates writes against osd_max_object_size (128 MiB). Anything between the two limits passes OSD validation then trips the assert, crashing the OSD and its replicas. _zero() already returned EIO for this case; mirror that in _write() and fix _zero()'s off-by-one (>= should be >, matching the <= in the assert). Signed-off-by: Kefu Chai --- diff --git a/src/crimson/os/seastore/seastore.cc b/src/crimson/os/seastore/seastore.cc index 02c4d9526525..35f0fa78dc9b 100644 --- a/src/crimson/os/seastore/seastore.cc +++ b/src/crimson/os/seastore/seastore.cc @@ -2151,6 +2151,17 @@ SeaStore::Shard::_write( ceph::bufferlist &&_bl, uint32_t fadvise_flags) { + // SeaStore reserves max_object_size of laddr space per object; + // ObjectDataHandler::prepare_data_reservation() ceph_assert()s that + // the requested size fits. Reject oversized writes here -- mirrors + // the corresponding check in _zero() -- so the OSD returns EIO to the + // client instead of aborting (and taking peer replicas with it). + if (offset + len > max_object_size) { + LOG_PREFIX(SeaStoreS::_write); + ERRORT("0x{:x}~0x{:x} > 0x{:x}", + *ctx.transaction, offset, len, max_object_size); + return crimson::ct_error::input_output_error::make(); + } const auto &object_size = onode.get_layout().size; if (offset + len > object_size) { onode.update_onode_size( @@ -2268,9 +2279,9 @@ SeaStore::Shard::_zero( objaddr_t offset, extent_len_t len) { - if (offset + len >= max_object_size) { + if (offset + len > max_object_size) { LOG_PREFIX(SeaStoreS::_zero); - ERRORT("0x{:x}~0x{:x} >= 0x{:x}", + ERRORT("0x{:x}~0x{:x} > 0x{:x}", *ctx.transaction, offset, len, max_object_size); return crimson::ct_error::input_output_error::make(); }