mirror of
https://github.com/ceph/ceph
synced 2025-02-17 16:07:37 +00:00
rgw/lc: Fix issues with non-current objects with instance empty
When the bucket versioning is enabled, old plain object entry is converted to versioned by updating its instance as "null" in its raw head/old object. However its instance remains empty in the bi list entry. Same is the case for the entries created after versioning is suspended and re-enabled. So to access such objects which are non-current, we need to set rgw_obj_key.instance as 1) "null" to read the actual raw obj and 2) empty while accessing/updating their bi entry. Fixes: https://tracker.ceph.com/issues/68402 Signed-off-by: Soumya Koduri <skoduri@redhat.com>
This commit is contained in:
parent
ee6523b618
commit
60149ade9d
@ -77,8 +77,9 @@ WRITE_CLASS_ENCODER(rgw_lc_multipart_upload_info)
|
||||
|
||||
static inline string get_key_instance(const rgw_obj_key& key)
|
||||
{
|
||||
if (!key.instance.empty() &&
|
||||
!key.have_null_instance()) {
|
||||
// if non-current entry, add versionID to the
|
||||
// transitioned object name including "null".
|
||||
if (!key.instance.empty()) {
|
||||
return "-" + key.instance;
|
||||
}
|
||||
return "";
|
||||
|
@ -5089,7 +5089,7 @@ int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx,
|
||||
|
||||
int RGWRados::transition_obj(RGWObjectCtx& obj_ctx,
|
||||
RGWBucketInfo& bucket_info,
|
||||
const rgw_obj& obj,
|
||||
rgw_obj obj,
|
||||
const rgw_placement_rule& placement_rule,
|
||||
const real_time& mtime,
|
||||
uint64_t olh_epoch,
|
||||
@ -5120,6 +5120,11 @@ int RGWRados::transition_obj(RGWObjectCtx& obj_ctx,
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
// bi expects empty instance for the entries created when bucket versioning
|
||||
// is not enabled or suspended.
|
||||
if (obj.key.instance == "null") {
|
||||
obj.key.instance.clear();
|
||||
}
|
||||
attrs.erase(RGW_ATTR_ID_TAG);
|
||||
attrs.erase(RGW_ATTR_TAIL_TAG);
|
||||
|
||||
|
@ -1234,7 +1234,7 @@ public:
|
||||
|
||||
int transition_obj(RGWObjectCtx& obj_ctx,
|
||||
RGWBucketInfo& bucket_info,
|
||||
const rgw_obj& obj,
|
||||
rgw_obj obj,
|
||||
const rgw_placement_rule& placement_rule,
|
||||
const real_time& mtime,
|
||||
uint64_t olh_epoch,
|
||||
|
@ -2792,6 +2792,13 @@ int RadosObject::write_cloud_tier(const DoutPrefixProvider* dpp,
|
||||
{
|
||||
rgw::sal::RadosPlacementTier* rtier = static_cast<rgw::sal::RadosPlacementTier*>(tier);
|
||||
map<string, bufferlist> attrs = get_attrs();
|
||||
rgw_obj_key& obj_key = get_key();
|
||||
// bi expects empty instance for the entries created when bucket versioning
|
||||
// is not enabled or suspended.
|
||||
if (obj_key.instance == "null") {
|
||||
obj_key.instance.clear();
|
||||
}
|
||||
|
||||
RGWRados::Object op_target(store->getRados(), bucket->get_info(), *rados_ctx, get_obj());
|
||||
RGWRados::Object::Write obj_op(&op_target);
|
||||
|
||||
|
@ -495,6 +495,14 @@ struct lc_op_ctx {
|
||||
octx(env.driver), dpp(dpp), wq(wq)
|
||||
{
|
||||
obj = bucket->get_object(o.key);
|
||||
/* once bucket versioning is enabled, the non-current entries with
|
||||
* instance empty should have instance set to "null" to be able
|
||||
* to correctly read its olh version entry.
|
||||
*/
|
||||
if (o.key.instance.empty() && bucket->versioned() && !o.is_current()) {
|
||||
rgw_obj_key& obj_key = obj->get_key();
|
||||
obj_key.instance = "null";
|
||||
}
|
||||
}
|
||||
|
||||
bool next_has_same_name(const std::string& key_name) {
|
||||
@ -1355,9 +1363,9 @@ public:
|
||||
int delete_tier_obj(lc_op_ctx& oc) {
|
||||
int ret = 0;
|
||||
|
||||
/* If bucket is versioned, create delete_marker for current version
|
||||
/* If bucket has versioning enabled, create delete_marker for current version
|
||||
*/
|
||||
if (! oc.bucket->versioned()) {
|
||||
if (! oc.bucket->versioning_enabled()) {
|
||||
ret =
|
||||
remove_expired_obj(oc.dpp, oc, true, {rgw::notify::ObjectTransition});
|
||||
ldpp_dout(oc.dpp, 20) << "delete_tier_obj Object(key:" << oc.o.key
|
||||
@ -1387,9 +1395,10 @@ public:
|
||||
|
||||
int transition_obj_to_cloud(lc_op_ctx& oc) {
|
||||
int ret{0};
|
||||
/* If CurrentVersion object, remove it & create delete marker */
|
||||
/* If CurrentVersion object & bucket has versioning enabled, remove it &
|
||||
* create delete marker */
|
||||
bool delete_object = (!oc.tier->retain_head_object() ||
|
||||
(oc.o.is_current() && oc.bucket->versioned()));
|
||||
(oc.o.is_current() && oc.bucket->versioning_enabled()));
|
||||
|
||||
/* notifications */
|
||||
auto& bucket = oc.bucket;
|
||||
|
Loading…
Reference in New Issue
Block a user