From 9e0f0059587fd059df5190d731ca7b15b388e527 Mon Sep 17 00:00:00 2001 From: Cory Snyder Date: Tue, 23 May 2023 09:43:38 +0000 Subject: [PATCH] rgw: is_olh() predicate should use user.rgw.olh.ver xattr The predicate which determines whether an object is an OLH object was previously based off of the user.rgw.olh.info xattr, but this xattr is not set when the OLH object is first created. This means that in cases where an error prevents that xattr from being set later, the OLH object is incorrectly interpreted as an empty unversioned object. This change modifies the is_olh function to use the user.rgw.olh.ver xattr. This xattr is set at the time of OLH creation and therefore ensures consistency. Fixes: https://tracker.ceph.com/issues/61359 Signed-off-by: Cory Snyder (cherry picked from commit 74ab3eb94a4177eacdac4fe48528542ba355ecfe) --- src/rgw/rgw_rados.cc | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 6f5484cd21ae8..1b84726231e8e 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -5456,7 +5456,7 @@ static void generate_fake_tag(const DoutPrefixProvider *dpp, rgw::sal::Store* st static bool is_olh(map& attrs) { - map::iterator iter = attrs.find(RGW_ATTR_OLH_INFO); + map::iterator iter = attrs.find(RGW_ATTR_OLH_VER); return (iter != attrs.end()); } @@ -6764,6 +6764,18 @@ int RGWRados::olh_init_modification_impl(const DoutPrefixProvider *dpp, const RG if (has_tag) { /* guard against racing writes */ bucket_index_guard_olh_op(dpp, state, op); + } else if (state.exists) { + // This is the case where a null versioned object already exists for this key + // but it hasn't been initialized as an OLH object yet. We immediately add + // the RGW_ATTR_OLH_INFO attr so that the OLH points back to itself and + // therefore effectively makes this an unobservable modification. + op.cmpxattr(RGW_ATTR_OLH_ID_TAG, CEPH_OSD_CMPXATTR_OP_EQ, bufferlist()); + RGWOLHInfo info; + info.target = olh_obj; + info.removed = false; + bufferlist bl; + encode(info, bl); + op.setxattr(RGW_ATTR_OLH_INFO, bl); } if (!has_tag) { @@ -7623,7 +7635,7 @@ int RGWRados::get_olh(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket return r; } - auto iter = attrset.find(RGW_ATTR_OLH_INFO); + auto iter = attrset.find(RGW_ATTR_OLH_VER); if (iter == attrset.end()) { /* not an olh */ return -EINVAL; } @@ -7725,10 +7737,14 @@ int RGWRados::follow_olh(const DoutPrefixProvider *dpp, const RGWBucketInfo& buc } } - auto iter = state->attrset.find(RGW_ATTR_OLH_INFO); + auto iter = state->attrset.find(RGW_ATTR_OLH_VER); if (iter == state->attrset.end()) { return -EINVAL; } + iter = state->attrset.find(RGW_ATTR_OLH_INFO); + if (iter == state->attrset.end()) { + return -ENOENT; + } RGWOLHInfo olh; int ret = decode_olh_info(dpp, cct, iter->second, &olh); -- 2.39.5