From: Alex Ainscow Date: Tue, 10 Jun 2025 09:54:13 +0000 (+0100) Subject: bluestore: Fix _setattr() with rare memory alignments X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=88bc731b9ef6a4b326378b9b721a5f9234f7a7f1;p=ceph.git bluestore: Fix _setattr() with rare memory alignments Fix an issue in BlueStore_setattr whereby if a buffer was contiguous and non-partial, then bluestore could completely drop the attribute. setattr seems to be rarely used outside of new EC. In new EC it is only used on non-primary shards, so this was only ever seen if the non-primary happened to be on the same OSD as the primary - this is transient and rare that scrubbing would actually catche the issue. Fixes: https://tracker.ceph.com/issues/71623 Signed-off-by: Alex Ainscow (cherry picked from commit d4e2d4977016bce22a4b9e779c5da54be2d4aaba) --- diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 2e627945e7174..d76442e9a57c0 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -17992,6 +17992,8 @@ int BlueStore::_remove(TransContext *txc, return r; } + + int BlueStore::_setattr(TransContext *txc, CollectionRef& c, OnodeRef& o, @@ -18002,18 +18004,13 @@ int BlueStore::_setattr(TransContext *txc, << " " << name << " (" << val.length() << " bytes)" << dendl; int r = 0; - if (!val.length()) { - auto& b = o->onode.attrs[name.c_str()] = bufferptr("", 0); - b.reassign_to_mempool(mempool::mempool_bluestore_cache_meta); - } else if (!val.is_contiguous()) { - val.rebuild(); - auto& b = o->onode.attrs[name.c_str()] = val.front(); - b.reassign_to_mempool(mempool::mempool_bluestore_cache_meta); - } else if (val.front().is_partial()) { + + if (!val.is_contiguous() || val.front().is_partial()) { val.rebuild(); - auto& b = o->onode.attrs[name.c_str()] = val.front(); - b.reassign_to_mempool(mempool::mempool_bluestore_cache_meta); } + auto& b = o->onode.attrs[name.c_str()] = val.front(); + b.reassign_to_mempool(mempool::mempool_bluestore_cache_meta); + txc->write_onode(o); dout(10) << __func__ << " " << c->cid << " " << o->oid << " " << name << " (" << val.length() << " bytes)"