From 88bc731b9ef6a4b326378b9b721a5f9234f7a7f1 Mon Sep 17 00:00:00 2001 From: Alex Ainscow Date: Tue, 10 Jun 2025 10:54:13 +0100 Subject: [PATCH] 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) --- src/os/bluestore/BlueStore.cc | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 2e627945e71..d76442e9a57 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)" -- 2.39.5