From bd11f19d59577aa2ee49b6399e68c414c02afc51 Mon Sep 17 00:00:00 2001 From: Daniel Gryniewicz Date: Thu, 9 May 2024 10:47:28 -0400 Subject: [PATCH] RGW: Remove get_obj_state()/set_obj_state from SAL RGWObjState is the state for the StoreObject class. It has historically been accessible via get_obj_state()/set_obj_state(), but the double pointer nature of this access has caused multiple bugs, and the RGWObjState itself is an implementation detail that doesn't need to be exposed. Instead, add a load_obj_state() that loads the state from the store, and use proper getters/setters for the data. Signed-off-by: Daniel Gryniewicz --- src/rgw/driver/d4n/rgw_sal_d4n.cc | 51 +++++++------- src/rgw/driver/daos/rgw_sal_daos.cc | 10 ++- src/rgw/driver/daos/rgw_sal_daos.h | 4 +- src/rgw/driver/motr/rgw_sal_motr.cc | 4 +- src/rgw/driver/motr/rgw_sal_motr.h | 2 +- src/rgw/driver/posix/rgw_sal_posix.cc | 67 ++++++++----------- src/rgw/driver/posix/rgw_sal_posix.h | 4 +- src/rgw/driver/rados/rgw_bucket.cc | 8 +-- src/rgw/driver/rados/rgw_cr_rados.cc | 16 ++--- src/rgw/driver/rados/rgw_rados.h | 2 +- src/rgw/driver/rados/rgw_sal_rados.cc | 8 ++- src/rgw/driver/rados/rgw_sal_rados.h | 4 +- src/rgw/rgw_admin.cc | 8 +-- src/rgw/rgw_lc.cc | 40 +++++------ src/rgw/rgw_op.cc | 53 +++++++-------- src/rgw/rgw_rest_s3.cc | 8 +-- src/rgw/rgw_rest_swift.cc | 14 ++-- src/rgw/rgw_sal.cc | 35 ---------- src/rgw/rgw_sal.h | 68 ++++++------------- src/rgw/rgw_sal_dbstore.cc | 3 +- src/rgw/rgw_sal_dbstore.h | 2 +- src/rgw/rgw_sal_filter.cc | 7 +- src/rgw/rgw_sal_filter.h | 14 +++- src/rgw/rgw_sal_store.h | 96 ++++++++++++++++++++++++++- 24 files changed, 265 insertions(+), 263 deletions(-) diff --git a/src/rgw/driver/d4n/rgw_sal_d4n.cc b/src/rgw/driver/d4n/rgw_sal_d4n.cc index 03d3295f3c1..4976d059675 100644 --- a/src/rgw/driver/d4n/rgw_sal_d4n.cc +++ b/src/rgw/driver/d4n/rgw_sal_d4n.cc @@ -255,28 +255,29 @@ int D4NFilterObject::get_obj_attrs(optional_yield y, const DoutPrefixProvider* d } else { /* Set metadata locally */ RGWQuotaInfo quota_info; - RGWObjState* astate; - this->get_obj_state(dpp, &astate, y); + this->load_obj_state(dpp, y); for (auto it = attrs.begin(); it != attrs.end(); ++it) { if (it->second.length() > 0) { if (it->first == "mtime") { - parse_time(it->second.c_str(), &astate->mtime); + ceph::real_time mtime; + parse_time(it->second.c_str(), &mtime); + this->set_mtime(mtime); attrs.erase(it->first); } else if (it->first == "object_size") { this->set_obj_size(std::stoull(it->second.c_str())); attrs.erase(it->first); } else if (it->first == "accounted_size") { - astate->accounted_size = std::stoull(it->second.c_str()); + this->set_accounted_size(std::stoull(it->second.c_str())); attrs.erase(it->first); } else if (it->first == "epoch") { - astate->epoch = std::stoull(it->second.c_str()); + this->set_epoch(std::stoull(it->second.c_str())); attrs.erase(it->first); } else if (it->first == "version_id") { this->set_instance(it->second.c_str()); attrs.erase(it->first); } else if (it->first == "this_zone_short_id") { - astate->zone_short_id = static_cast(std::stoul(it->second.c_str())); + this->set_short_zone_id(static_cast(std::stoul(it->second.c_str()))); attrs.erase(it->first); } else if (it->first == "user_quota.max_size") { quota_info.max_size = std::stoull(it->second.c_str()); @@ -293,8 +294,6 @@ int D4NFilterObject::get_obj_attrs(optional_yield y, const DoutPrefixProvider* d } } - this->set_obj_state(*astate); - /* Set attributes locally */ if (this->set_attrs(attrs) < 0) { ldpp_dout(dpp, 10) << "D4NFilterObject::" << __func__ << "(): D4NFilterObject set_attrs method failed." << dendl; @@ -390,29 +389,29 @@ int D4NFilterObject::D4NFilterReadOp::prepare(optional_yield y, const DoutPrefix ldpp_dout(dpp, 10) << "D4NFilterObject::D4NFilterReadOp::" << __func__ << "(): CacheDriver get_attrs method failed." << dendl; } else { /* Set metadata locally */ - RGWObjState* astate; RGWQuotaInfo quota_info; - source->get_obj_state(dpp, &astate, y); + source->load_obj_state(dpp, y); for (auto& attr : attrs) { if (attr.second.length() > 0) { if (attr.first == "mtime") { - parse_time(attr.second.c_str(), &astate->mtime); - attrs.erase(attr.first); + ceph::real_time mtime; + parse_time(attr.second.c_str(), &mtime); + source->set_mtime(mtime); } else if (attr.first == "object_size") { source->set_obj_size(std::stoull(attr.second.c_str())); attrs.erase(attr.first); } else if (attr.first == "accounted_size") { - astate->accounted_size = std::stoull(attr.second.c_str()); + source->set_accounted_size(std::stoull(attr.second.c_str())); attrs.erase(attr.first); } else if (attr.first == "epoch") { - astate->epoch = std::stoull(attr.second.c_str()); + source->set_epoch(std::stoull(attr.second.c_str())); attrs.erase(attr.first); } else if (attr.first == "version_id") { source->set_instance(attr.second.c_str()); attrs.erase(attr.first); } else if (attr.first == "source_zone_short_id") { - astate->zone_short_id = static_cast(std::stoul(attr.second.c_str())); + source->set_short_zone_id(static_cast(std::stoul(attr.second.c_str()))); attrs.erase(attr.first); } else if (attr.first == "user_quota.max_size") { quota_info.max_size = std::stoull(attr.second.c_str()); @@ -426,7 +425,6 @@ int D4NFilterObject::D4NFilterReadOp::prepare(optional_yield y, const DoutPrefix ldpp_dout(dpp, 20) << "D4NFilterObject::D4NFilterReadOp::" << __func__ << "(): Unexpected attribute; not locally set." << dendl; } } - source->set_obj_state(*astate); /* Set attributes locally */ if (source->set_attrs(attrs) < 0) @@ -435,14 +433,12 @@ int D4NFilterObject::D4NFilterReadOp::prepare(optional_yield y, const DoutPrefix } //versioned objects have instance set to versionId, and get_oid() returns oid containing instance, hence using id tag as version for non versioned objects only - if (! this->source->have_instance()) { - RGWObjState* state = nullptr; - if (this->source->get_obj_state(dpp, &state, y) == 0) { - auto it = state->attrset.find(RGW_ATTR_ID_TAG); - if (it != state->attrset.end()) { - bufferlist bl = it->second; - this->source->set_object_version(bl.c_str()); - ldpp_dout(dpp, 20) << __func__ << "id tag version is: " << this->source->get_object_version() << dendl; + if (! source->have_instance()) { + if (source->load_obj_state(dpp, y) == 0) { + bufferlist bl; + if (source->get_attr(RGW_ATTR_ID_TAG, bl)) { + source->set_object_version(bl.c_str()); + ldpp_dout(dpp, 20) << __func__ << "id tag version is: " << source->get_object_version() << dendl; } else { ldpp_dout(dpp, 20) << __func__ << "Failed to find id tag" << dendl; } @@ -942,8 +938,7 @@ int D4NFilterWriter::complete(size_t accounted_size, const std::string& etag, rgw::sal::Attrs baseAttrs = obj->get_attrs(); rgw::sal::Attrs attrs_temp = baseAttrs; buffer::list bl; - RGWObjState* astate; - obj->get_obj_state(save_dpp, &astate, rctx.y); + obj->load_obj_state(save_dpp, rctx.y); bl.append(to_iso_8601(obj->get_mtime())); baseAttrs.insert({"mtime", bl}); @@ -957,7 +952,7 @@ int D4NFilterWriter::complete(size_t accounted_size, const std::string& etag, baseAttrs.insert({"accounted_size", bl}); bl.clear(); - bl.append(std::to_string(astate->epoch)); + bl.append(std::to_string(obj->get_epoch())); baseAttrs.insert({"epoch", bl}); bl.clear(); @@ -973,7 +968,7 @@ int D4NFilterWriter::complete(size_t accounted_size, const std::string& etag, auto iter = attrs_temp.find(RGW_ATTR_SOURCE_ZONE); if (iter != attrs_temp.end()) { - bl.append(std::to_string(astate->zone_short_id)); + bl.append(std::to_string(obj->get_short_zone_id())); baseAttrs.insert({"source_zone_short_id", bl}); bl.clear(); } else { diff --git a/src/rgw/driver/daos/rgw_sal_daos.cc b/src/rgw/driver/daos/rgw_sal_daos.cc index f8f60d82d02..b105d9684b7 100644 --- a/src/rgw/driver/daos/rgw_sal_daos.cc +++ b/src/rgw/driver/daos/rgw_sal_daos.cc @@ -868,13 +868,11 @@ std::unique_ptr DaosStore::get_lua_manager(const DoutPrefixProvider return std::make_unique(this, dpp, luarocks_path); } -int DaosObject::get_obj_state(const DoutPrefixProvider* dpp, - RGWObjState** _state, optional_yield y, - bool follow_olh) { +int DaosObject::load_obj_state(const DoutPrefixProvider* dpp, + optional_yield y, bool follow_olh) { // Get object's metadata (those stored in rgw_bucket_dir_entry) - ldpp_dout(dpp, 20) << "DEBUG: get_obj_state" << dendl; + ldpp_dout(dpp, 20) << "DEBUG: load_obj_state" << dendl; rgw_bucket_dir_entry ent; - *_state = &state; // state is required even if a failure occurs int ret = get_dir_entry_attrs(dpp, &ent); if (ret != 0) { @@ -1158,7 +1156,7 @@ std::unique_ptr DaosObject::get_delete_op() { DaosObject::DaosDeleteOp::DaosDeleteOp(DaosObject* _source) : source(_source) {} -// Implementation of DELETE OBJ also requires DaosObject::get_obj_state() +// Implementation of DELETE OBJ also requires DaosObject::load_obj_state() // to retrieve and set object's state from object's metadata. // // TODO: diff --git a/src/rgw/driver/daos/rgw_sal_daos.h b/src/rgw/driver/daos/rgw_sal_daos.h index cf1583fc174..8b40c645caf 100644 --- a/src/rgw/driver/daos/rgw_sal_daos.h +++ b/src/rgw/driver/daos/rgw_sal_daos.h @@ -617,8 +617,8 @@ class DaosObject : public StoreObject { return 0; } - virtual int get_obj_state(const DoutPrefixProvider* dpp, RGWObjState** state, - optional_yield y, bool follow_olh = true) override; + virtual int load_obj_state(const DoutPrefixProvider *dpp, optional_yield y, + bool follow_olh = true) override; virtual int set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, Attrs* delattrs, optional_yield y) override; virtual int get_obj_attrs(optional_yield y, const DoutPrefixProvider* dpp, diff --git a/src/rgw/driver/motr/rgw_sal_motr.cc b/src/rgw/driver/motr/rgw_sal_motr.cc index ae86ec9e7d3..7934b3a6173 100644 --- a/src/rgw/driver/motr/rgw_sal_motr.cc +++ b/src/rgw/driver/motr/rgw_sal_motr.cc @@ -1126,7 +1126,7 @@ std::unique_ptr MotrStore::get_lua_manager(const DoutPrefixProvider return std::make_unique(this, dpp, luarocks_path); } -int MotrObject::get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **_state, optional_yield y, bool follow_olh) +int MotrObject::load_obj_state(const DoutPrefixProvider* dpp, optional_yield y, bool follow_olh) { // Get object's metadata (those stored in rgw_bucket_dir_entry). bufferlist bl; @@ -1449,7 +1449,7 @@ MotrObject::MotrDeleteOp::MotrDeleteOp(MotrObject *_source) : source(_source) { } -// Implementation of DELETE OBJ also requires MotrObject::get_obj_state() +// Implementation of DELETE OBJ also requires MotrObject::load_obj_state() // to retrieve and set object's state from object's metadata. // // TODO: diff --git a/src/rgw/driver/motr/rgw_sal_motr.h b/src/rgw/driver/motr/rgw_sal_motr.h index e278728c7e7..caf7c8667f7 100644 --- a/src/rgw/driver/motr/rgw_sal_motr.h +++ b/src/rgw/driver/motr/rgw_sal_motr.h @@ -676,7 +676,7 @@ class MotrObject : public StoreObject { const DoutPrefixProvider* dpp, optional_yield y) override; virtual RGWAccessControlPolicy& get_acl(void) override { return acls; } virtual int set_acl(const RGWAccessControlPolicy& acl) override { acls = acl; return 0; } - virtual int get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **state, optional_yield y, bool follow_olh = true) override; + virtual int load_obj_state(const DoutPrefixProvider* dpp, optional_yield y, bool follow_olh = true) override; virtual int set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, Attrs* delattrs, optional_yield y) override; virtual int get_obj_attrs(optional_yield y, const DoutPrefixProvider* dpp, rgw_obj* target_obj = NULL) override; virtual int modify_obj_attrs(const char* attr_name, bufferlist& attr_val, optional_yield y, const DoutPrefixProvider* dpp) override; diff --git a/src/rgw/driver/posix/rgw_sal_posix.cc b/src/rgw/driver/posix/rgw_sal_posix.cc index 9b1b34fa9e4..ea4d154e0c8 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.cc +++ b/src/rgw/driver/posix/rgw_sal_posix.cc @@ -36,17 +36,6 @@ const std::string mp_ns = "multipart"; const std::string MP_OBJ_PART_PFX = "part-"; const std::string MP_OBJ_HEAD_NAME = MP_OBJ_PART_PFX + "00000"; -static inline bool get_attr(Attrs& attrs, const char* name, bufferlist& bl) -{ - auto iter = attrs.find(name); - if (iter == attrs.end()) { - return false; - } - - bl = iter->second; - return true; -} - static inline rgw_obj_key decode_obj_key(const char* fname) { std::string dname, oname, ns; @@ -621,7 +610,7 @@ int POSIXObject::fill_bde(const DoutPrefixProvider *dpp, optional_yield y, rgw_b bde.meta.storage_class = RGW_STORAGE_CLASS_STANDARD; bde.meta.appendable = true; bufferlist etag_bl; - if (rgw::sal::get_attr(get_attrs(), RGW_ATTR_ETAG, etag_bl)) { + if (get_attr(RGW_ATTR_ETAG, etag_bl)) { bde.meta.etag = etag_bl.to_str(); } @@ -643,7 +632,7 @@ int POSIXDriver::mint_listing_entry(const std::string &bname, obj = b->get_object(decode_obj_key(bde.key.name.c_str())); pobj = static_cast(obj.get()); - if (!pobj->exists(nullptr)) { + if (!pobj->check_exists(nullptr)) { ret = errno; return -ret; } @@ -674,7 +663,7 @@ int POSIXBucket::fill_cache(const DoutPrefixProvider* dpp, optional_yield y, obj = get_object(decode_obj_key(name)); pobj = static_cast(obj.get()); - if (!pobj->exists(dpp)) { + if (!pobj->check_exists(dpp)) { ret = errno; ldpp_dout(dpp, 0) << "ERROR: could not stat object " << name << ": " << cpp_strerror(ret) << dendl; @@ -892,11 +881,11 @@ int POSIXBucket::load_bucket(const DoutPrefixProvider* dpp, optional_yield y) } get_x_attrs(y, dpp, dir_fd, attrs, get_name()); - bufferlist bl; - if (get_attr(attrs, RGW_POSIX_ATTR_BUCKET_INFO, bl)) { + auto iter = attrs.find(RGW_POSIX_ATTR_BUCKET_INFO); + if (iter != attrs.end()) { // Proper bucket with saved info try { - auto bufit = bl.cbegin(); + auto bufit = iter->second.cbegin(); decode(info, bufit); } catch (buffer::error &err) { ldout(driver->ctx(), 0) << "ERROR: " << __func__ << ": failed to decode " RGW_POSIX_ATTR_BUCKET_INFO " attr" << dendl; @@ -1283,7 +1272,7 @@ int POSIXBucket::rename(const DoutPrefixProvider* dpp, optional_yield y, Object* std::string dst_fname = to->get_fname(); int flags = 0; - if (to->exists(dpp)) { + if (to->check_exists(dpp)) { flags = RENAME_EXCHANGE; } // swap @@ -1404,7 +1393,7 @@ int POSIXBucket::copy(const DoutPrefixProvider *dpp, optional_yield y, sobj = this->get_object(decode_obj_key(name)); sop = static_cast(sobj.get()); - if (!sop->exists(dpp)) { + if (!sop->check_exists(dpp)) { ret = errno; ldpp_dout(dpp, 0) << "ERROR: could not stat object " << name << ": " << cpp_strerror(ret) << dendl; @@ -1529,7 +1518,7 @@ int POSIXObject::copy_object(const ACLOwner& owner, } // Source must exist, and we need to know if it's a shadow obj - if (!exists(dpp)) { + if (!check_exists(dpp)) { ret = errno; ldpp_dout(dpp, 0) << "ERROR: could not stat object " << get_name() << ": " << cpp_strerror(ret) << dendl; @@ -1543,13 +1532,12 @@ int POSIXObject::copy_object(const ACLOwner& owner, } } -int POSIXObject::get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **pstate, optional_yield y, bool follow_olh) +int POSIXObject::load_obj_state(const DoutPrefixProvider* dpp, optional_yield y, bool follow_olh) { int ret = stat(dpp); if (ret < 0) { return ret; } - *pstate = &state; return 0; } @@ -1618,7 +1606,7 @@ int POSIXObject::delete_obj_attrs(const DoutPrefixProvider* dpp, const char* att bool POSIXObject::is_expired() { bufferlist bl; - if (get_attr(state.attrset, RGW_ATTR_DELETE_AT, bl)) { + if (get_attr(RGW_ATTR_DELETE_AT, bl)) { utime_t delete_at; try { auto bufit = bl.cbegin(); @@ -1652,7 +1640,7 @@ std::unique_ptr POSIXObject::get_serializer(const DoutPrefixProvid int MPPOSIXSerializer::try_lock(const DoutPrefixProvider *dpp, utime_t dur, optional_yield y) { - if (!obj->exists(dpp)) { + if (!obj->check_exists(dpp)) { return -ENOENT; } @@ -1822,7 +1810,7 @@ int POSIXObject::get_owner(const DoutPrefixProvider *dpp, optional_yield y, std: { bufferlist bl; rgw_user u; - if (!rgw::sal::get_attr(get_attrs(), RGW_POSIX_ATTR_OWNER, bl)) { + if (!get_attr(RGW_POSIX_ATTR_OWNER, bl)) { ldpp_dout(dpp, 0) << "ERROR: " << __func__ << ": No " RGW_POSIX_ATTR_OWNER " attr" << dendl; return -EINVAL; @@ -2086,7 +2074,7 @@ int POSIXObject::POSIXReadOp::prepare(optional_yield y, const DoutPrefixProvider return ret; bufferlist etag_bl; - if (!rgw::sal::get_attr(source->get_attrs(), RGW_ATTR_ETAG, etag_bl)) { + if (!source->get_attr(RGW_ATTR_ETAG, etag_bl)) { /* Sideloaded file. Generate necessary attributes. Only done once. */ int ret = source->generate_attrs(dpp, y); if (ret < 0) { @@ -2095,7 +2083,7 @@ int POSIXObject::POSIXReadOp::prepare(optional_yield y, const DoutPrefixProvider } } - if (!rgw::sal::get_attr(source->get_attrs(), RGW_ATTR_ETAG, etag_bl)) { + if (!source->get_attr(RGW_ATTR_ETAG, etag_bl)) { return -EINVAL; } @@ -2222,13 +2210,13 @@ int POSIXObject::generate_mp_etag(const DoutPrefixProvider* dpp, optional_yield return ret; } bufferlist etag_bl; - if (!get_attr(shadow_obj->get_attrs(), RGW_ATTR_ETAG, etag_bl)) { + if (!shadow_obj->get_attr(RGW_ATTR_ETAG, etag_bl)) { // Generate part's etag ret = shadow_obj->generate_etag(dpp, y); if (ret < 0) return ret; } - if (!get_attr(shadow_obj->get_attrs(), RGW_ATTR_ETAG, etag_bl)) { + if (!shadow_obj->get_attr(RGW_ATTR_ETAG, etag_bl)) { // Can't get etag. return -EINVAL; } @@ -2359,13 +2347,13 @@ int POSIXObject::POSIXReadOp::iterate(const DoutPrefixProvider* dpp, int64_t ofs int POSIXObject::POSIXReadOp::get_attr(const DoutPrefixProvider* dpp, const char* name, bufferlist& dest, optional_yield y) { - if (!source->exists(dpp)) { + if (!source->check_exists(dpp)) { return -ENOENT; } if (source->get_obj_attrs(y, dpp) < 0) { return -ENODATA; } - if (!rgw::sal::get_attr(source->get_attrs(), name, dest)) { + if (!source->get_attr(name, dest)) { return -ENODATA; } @@ -2451,9 +2439,8 @@ int POSIXMultipartPart::load(const DoutPrefixProvider* dpp, optional_yield y, shadow = std::make_unique(driver, key, upload->get_shadow()); - RGWObjState* pstate; // Stat the shadow object to get things like size - int ret = shadow->get_obj_state(dpp, &pstate, y); + int ret = shadow->load_obj_state(dpp, y); if (ret < 0) { return ret; } @@ -2767,7 +2754,7 @@ int POSIXMultipartUpload::get_info(const DoutPrefixProvider *dpp, optional_yield } } bufferlist bl; - if (!get_attr(meta_obj->get_attrs(), RGW_POSIX_ATTR_MPUPLOAD, bl)) { + if (!meta_obj->get_attr(RGW_POSIX_ATTR_MPUPLOAD, bl)) { ldpp_dout(dpp, 0) << " ERROR: could not get meta object attrs for mp upload " << get_key() << dendl; return ret; @@ -2825,12 +2812,12 @@ int POSIXMultipartWriter::complete(size_t accounted_size, const std::string& eta if (if_match) { if (strcmp(if_match, "*") == 0) { // test the object is existing - if (!obj->exists(dpp)) { + if (!obj->check_exists(dpp)) { return -ERR_PRECONDITION_FAILED; } } else { bufferlist bl; - if (!get_attr(obj->get_attrs(), RGW_ATTR_ETAG, bl)) { + if (!obj->get_attr(RGW_ATTR_ETAG, bl)) { return -ERR_PRECONDITION_FAILED; } if (strncmp(if_match, bl.c_str(), bl.length()) != 0) { @@ -2892,12 +2879,12 @@ int POSIXAtomicWriter::complete(size_t accounted_size, const std::string& etag, if (if_match) { if (strcmp(if_match, "*") == 0) { // test the object is existing - if (!obj.exists(dpp)) { + if (!obj.check_exists(dpp)) { return -ERR_PRECONDITION_FAILED; } } else { bufferlist bl; - if (!get_attr(obj.get_attrs(), RGW_ATTR_ETAG, bl)) { + if (!obj.get_attr(RGW_ATTR_ETAG, bl)) { return -ERR_PRECONDITION_FAILED; } if (strncmp(if_match, bl.c_str(), bl.length()) != 0) { @@ -2908,12 +2895,12 @@ int POSIXAtomicWriter::complete(size_t accounted_size, const std::string& etag, if (if_nomatch) { if (strcmp(if_nomatch, "*") == 0) { // test the object is not existing - if (obj.exists(dpp)) { + if (obj.check_exists(dpp)) { return -ERR_PRECONDITION_FAILED; } } else { bufferlist bl; - if (!get_attr(obj.get_attrs(), RGW_ATTR_ETAG, bl)) { + if (!obj.get_attr(RGW_ATTR_ETAG, bl)) { return -ERR_PRECONDITION_FAILED; } if (strncmp(if_nomatch, bl.c_str(), bl.length()) == 0) { diff --git a/src/rgw/driver/posix/rgw_sal_posix.h b/src/rgw/driver/posix/rgw_sal_posix.h index 587bf783e90..ceb3d0b7ff3 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.h +++ b/src/rgw/driver/posix/rgw_sal_posix.h @@ -339,7 +339,7 @@ public: const DoutPrefixProvider* dpp, optional_yield y) override; virtual RGWAccessControlPolicy& get_acl(void) override { return acls; } virtual int set_acl(const RGWAccessControlPolicy& acl) override { acls = acl; return 0; } - virtual int get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **state, optional_yield y, bool follow_olh = true) override; + virtual int load_obj_state(const DoutPrefixProvider* dpp, optional_yield y, bool follow_olh = true) override; virtual int set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, Attrs* delattrs, optional_yield y) override; virtual int get_obj_attrs(optional_yield y, const DoutPrefixProvider* dpp, @@ -393,7 +393,7 @@ public: void gen_temp_fname(); /* TODO dang Escape the object name for file use */ const std::string get_fname(); - bool exists(const DoutPrefixProvider* dpp) { stat(dpp); return state.exists; } + bool check_exists(const DoutPrefixProvider* dpp) { stat(dpp); return state.exists; } int get_owner(const DoutPrefixProvider *dpp, optional_yield y, std::unique_ptr *owner); int copy(const DoutPrefixProvider *dpp, optional_yield y, POSIXBucket *sb, POSIXBucket *db, POSIXObject *dobj); diff --git a/src/rgw/driver/rados/rgw_bucket.cc b/src/rgw/driver/rados/rgw_bucket.cc index ff6325e222a..08de61b172b 100644 --- a/src/rgw/driver/rados/rgw_bucket.cc +++ b/src/rgw/driver/rados/rgw_bucket.cc @@ -667,13 +667,13 @@ static int check_index_olh(rgw::sal::RadosStore* const rados_store, } } else { std::unique_ptr object = bucket->get_object({olh_entry.key.name}); - RGWObjState *state; - ret = object->get_obj_state(dpp, &state, y, false); + ret = object->load_obj_state(dpp, y, false); if (ret < 0) { - ldpp_dout(dpp, -1) << "ERROR failed to get state for: " << olh_entry.key.name << " get_obj_state(): " << cpp_strerror(-ret) << dendl; + ldpp_dout(dpp, -1) << "ERROR failed to load state for: " << olh_entry.key.name << " load_obj_state(): " << cpp_strerror(-ret) << dendl; continue; } - ret = store->update_olh(dpp, obj_ctx, state, bucket->get_info(), obj, y); + RGWObjState& state = static_cast(object.get())->get_state(); + ret = store->update_olh(dpp, obj_ctx, &state, bucket->get_info(), obj, y); if (ret < 0) { ldpp_dout(dpp, -1) << "ERROR failed to update olh for: " << olh_entry.key.name << " update_olh(): " << cpp_strerror(-ret) << dendl; continue; diff --git a/src/rgw/driver/rados/rgw_cr_rados.cc b/src/rgw/driver/rados/rgw_cr_rados.cc index 396c556926f..5e62bfbb76b 100644 --- a/src/rgw/driver/rados/rgw_cr_rados.cc +++ b/src/rgw/driver/rados/rgw_cr_rados.cc @@ -902,26 +902,24 @@ int RGWAsyncRemoveObj::_send_request(const DoutPrefixProvider *dpp) obj->set_atomic(); - RGWObjState *state; - - int ret = obj->get_obj_state(dpp, &state, null_yield); + int ret = obj->load_obj_state(dpp, null_yield); if (ret < 0) { - ldpp_dout(dpp, 20) << __func__ << "(): get_obj_state() obj=" << obj << " returned ret=" << ret << dendl; + ldpp_dout(dpp, 20) << __func__ << "(): load_obj_state() obj=" << obj << " returned ret=" << ret << dendl; return ret; } /* has there been any racing object write? */ - if (del_if_older && (state->mtime > timestamp)) { - ldpp_dout(dpp, 20) << __func__ << "(): skipping object removal obj=" << obj << " (obj mtime=" << state->mtime << ", request timestamp=" << timestamp << ")" << dendl; + if (del_if_older && (obj->get_mtime() > timestamp)) { + ldpp_dout(dpp, 20) << __func__ << "(): skipping object removal obj=" << obj << " (obj mtime=" << obj->get_mtime() << ", request timestamp=" << timestamp << ")" << dendl; return 0; } RGWAccessControlPolicy policy; /* decode policy */ - map::iterator iter = state->attrset.find(RGW_ATTR_ACL); - if (iter != state->attrset.end()) { - auto bliter = iter->second.cbegin(); + bufferlist bl; + if (obj->get_attr(RGW_ATTR_ACL, bl)) { + auto bliter = bl.cbegin(); try { policy.decode(bliter); } catch (buffer::error& err) { diff --git a/src/rgw/driver/rados/rgw_rados.h b/src/rgw/driver/rados/rgw_rados.h index 481a94a140d..f1e435fe36a 100644 --- a/src/rgw/driver/rados/rgw_rados.h +++ b/src/rgw/driver/rados/rgw_rados.h @@ -30,7 +30,7 @@ #include "rgw_sync_module.h" #include "rgw_trim_bilog.h" #include "rgw_service.h" -#include "rgw_sal.h" +#include "rgw_sal_store.h" #include "rgw_aio.h" #include "rgw_d3n_cacherequest.h" diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc index f1d7b18be4f..eace9df5f3f 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.cc +++ b/src/rgw/driver/rados/rgw_sal_rados.cc @@ -2254,9 +2254,11 @@ RadosObject::~RadosObject() delete rados_ctx; } -int RadosObject::get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **pstate, optional_yield y, bool follow_olh) +int RadosObject::load_obj_state(const DoutPrefixProvider* dpp, optional_yield y, bool follow_olh) { - int ret = store->getRados()->get_obj_state(dpp, rados_ctx, bucket->get_info(), get_obj(), pstate, &manifest, follow_olh, y); + RGWObjState *pstate{nullptr}; + + int ret = store->getRados()->get_obj_state(dpp, rados_ctx, bucket->get_info(), get_obj(), &pstate, &manifest, follow_olh, y); if (ret < 0) { return ret; } @@ -2266,7 +2268,7 @@ int RadosObject::get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **psta bool is_atomic = state.is_atomic; bool prefetch_data = state.prefetch_data; - state = **pstate; + state = *pstate; state.obj = obj; state.is_atomic = is_atomic; diff --git a/src/rgw/driver/rados/rgw_sal_rados.h b/src/rgw/driver/rados/rgw_sal_rados.h index 9f5d021987a..f880319b56e 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.h +++ b/src/rgw/driver/rados/rgw_sal_rados.h @@ -591,7 +591,9 @@ class RadosObject : public StoreObject { StoreObject::set_compressed(); } - virtual int get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **state, optional_yield y, bool follow_olh = true) override; + /* For rgw_admin.cc */ + RGWObjState& get_state() { return state; } + virtual int load_obj_state(const DoutPrefixProvider* dpp, optional_yield y, bool follow_olh = true) override; virtual int set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, Attrs* delattrs, optional_yield y) override; virtual int get_obj_attrs(optional_yield y, const DoutPrefixProvider* dpp, rgw_obj* target_obj = NULL) override; virtual int modify_obj_attrs(const char* attr_name, bufferlist& attr_val, optional_yield y, const DoutPrefixProvider* dpp) override; diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 61f5477d2d5..cfe0d944b58 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -7789,14 +7789,14 @@ next: std::unique_ptr obj = bucket->get_object(object); - RGWObjState *state; - - ret = obj->get_obj_state(dpp(), &state, null_yield); + ret = obj->load_obj_state(dpp(), null_yield); if (ret < 0) { return -ret; } - ret = static_cast(driver)->getRados()->bucket_index_read_olh_log(dpp(), bucket->get_info(), *state, obj->get_obj(), 0, &log, &is_truncated, null_yield); + RGWObjState& state = static_cast(obj.get())->get_state(); + + ret = static_cast(driver)->getRados()->bucket_index_read_olh_log(dpp(), bucket->get_info(), state, obj->get_obj(), 0, &log, &is_truncated, null_yield); if (ret < 0) { cerr << "ERROR: failed reading olh: " << cpp_strerror(-ret) << std::endl; return -ret; diff --git a/src/rgw/rgw_lc.cc b/src/rgw/rgw_lc.cc index a92272fdeec..b4f11c83bcf 100644 --- a/src/rgw/rgw_lc.cc +++ b/src/rgw/rgw_lc.cc @@ -514,8 +514,7 @@ static bool pass_size_limit_checks(const DoutPrefixProvider *dpp, lc_op_ctx& oc) auto& o = oc.o; std::unique_ptr obj = bucket->get_object(o.key); - RGWObjState *obj_state{nullptr}; - ret = obj->get_obj_state(dpp, &obj_state, null_yield, true); + ret = obj->load_obj_state(dpp, null_yield, true); if (ret < 0) { return false; } @@ -524,10 +523,10 @@ static bool pass_size_limit_checks(const DoutPrefixProvider *dpp, lc_op_ctx& oc) bool lt_p{true}; if (op.size_gt) { - gt_p = (obj_state->size > op.size_gt.get()); + gt_p = (obj->get_obj_size() > op.size_gt.get()); } if (op.size_lt) { - lt_p = (obj_state->size < op.size_lt.get()); + lt_p = (obj->get_obj_size() < op.size_lt.get()); } return gt_p && lt_p; @@ -585,15 +584,14 @@ static int remove_expired_obj(const DoutPrefixProvider* dpp, } auto obj = oc.bucket->get_object(obj_key); - RGWObjState* obj_state{nullptr}; string etag; - ret = obj->get_obj_state(dpp, &obj_state, null_yield, true); + ret = obj->load_obj_state(dpp, null_yield, true); if (ret < 0) { return ret; } - auto iter = obj_state->attrset.find(RGW_ATTR_ETAG); - if (iter != obj_state->attrset.end()) { - etag = rgw_bl_str(iter->second); + bufferlist bl; + if (obj->get_attr(RGW_ATTR_ETAG, bl)) { + etag = rgw_bl_str(bl); } std::unique_ptr del_op @@ -627,7 +625,7 @@ static int remove_expired_obj(const DoutPrefixProvider* dpp, fmt::format("ERROR: {} failed, with error: {}", __func__, ret) << dendl; } else { // send request to notification manager - int publish_ret = notify->publish_commit(dpp, obj_state->size, + int publish_ret = notify->publish_commit(dpp, obj->get_obj_size(), ceph::real_clock::now(), etag, version_id); @@ -894,15 +892,14 @@ int RGWLC::handle_multipart_expiration(rgw::sal::Bucket* target, auto mpu = target->get_multipart_upload(key.name); auto sal_obj = target->get_object(key); - RGWObjState* obj_state{nullptr}; string etag; - ret = sal_obj->get_obj_state(this, &obj_state, null_yield, true); + ret = sal_obj->load_obj_state(this, null_yield, true); if (ret < 0) { return ret; } - auto iter = obj_state->attrset.find(RGW_ATTR_ETAG); - if (iter != obj_state->attrset.end()) { - etag = rgw_bl_str(iter->second); + bufferlist bl; + if (sal_obj->get_attr(RGW_ATTR_ETAG, bl)) { + etag = rgw_bl_str(bl); } std::unique_ptr notify @@ -925,7 +922,7 @@ int RGWLC::handle_multipart_expiration(rgw::sal::Bucket* target, ret = mpu->abort(this, cct, null_yield); if (ret == 0) { int publish_ret = notify->publish_commit( - this, obj_state->size, + this, sal_obj->get_obj_size(), ceph::real_clock::now(), etag, version_id); @@ -1414,15 +1411,14 @@ public: auto& bucket = oc.bucket; auto& obj = oc.obj; - RGWObjState* obj_state{nullptr}; string etag; - ret = obj->get_obj_state(oc.dpp, &obj_state, null_yield, true); + ret = obj->load_obj_state(oc.dpp, null_yield, true); if (ret < 0) { return ret; } - auto iter = obj_state->attrset.find(RGW_ATTR_ETAG); - if (iter != obj_state->attrset.end()) { - etag = rgw_bl_str(iter->second); + bufferlist bl; + if (obj->get_attr(RGW_ATTR_ETAG, bl)) { + etag = rgw_bl_str(bl); } rgw::notify::EventTypeList event_types; @@ -1458,7 +1454,7 @@ public: return ret; } else { // send request to notification manager - int publish_ret = notify->publish_commit(oc.dpp, obj_state->size, + int publish_ret = notify->publish_commit(oc.dpp, obj->get_obj_size(), ceph::real_clock::now(), etag, version_id); diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 76fbb332e6b..04099b149ae 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -4254,14 +4254,13 @@ void RGWPutObj::execute(optional_yield y) auto obj = bucket->get_object(rgw_obj_key(copy_source_object_name, copy_source_version_id)); - RGWObjState *astate; - op_ret = obj->get_obj_state(this, &astate, s->yield); + op_ret = obj->load_obj_state(this, s->yield); if (op_ret < 0) { ldpp_dout(this, 0) << "ERROR: get copy source obj state returned with error" << op_ret << dendl; return; } bufferlist bl; - if (astate->get_attr(RGW_ATTR_MANIFEST, bl)) { + if (obj->get_attr(RGW_ATTR_MANIFEST, bl)) { RGWObjManifest m; try{ decode(m, bl); @@ -4280,11 +4279,11 @@ void RGWPutObj::execute(optional_yield y) } } - if (!astate->exists){ + if (!obj->exists()){ op_ret = -ENOENT; return; } - lst = astate->accounted_size - 1; + lst = obj->get_accounted_size() - 1; } else { lst = copy_source_range_lst; } @@ -5119,9 +5118,9 @@ void RGWDeleteObj::execute(optional_yield y) uint64_t obj_size = 0; std::string etag; { - RGWObjState* astate = nullptr; + int state_loaded = -1; bool check_obj_lock = s->object->have_instance() && s->bucket->get_info().obj_lock_enabled(); - op_ret = s->object->get_obj_state(this, &astate, s->yield, true); + op_ret = state_loaded = s->object->load_obj_state(this, s->yield, true); if (op_ret < 0) { if (need_object_expiration() || multipart_delete) { return; @@ -5137,15 +5136,15 @@ void RGWDeleteObj::execute(optional_yield y) } } } else { - obj_size = astate->size; - etag = astate->attrset[RGW_ATTR_ETAG].to_str(); + obj_size = s->object->get_obj_size(); + etag = s->object->get_attrs()[RGW_ATTR_ETAG].to_str(); } // ignore return value from get_obj_attrs in all other cases op_ret = 0; if (check_obj_lock) { - ceph_assert(astate); - int object_lock_response = verify_object_lock(this, astate->attrset, bypass_perm, bypass_governance_mode); + ceph_assert(state_loaded == 0); + int object_lock_response = verify_object_lock(this, s->object->get_attrs(), bypass_perm, bypass_governance_mode); if (object_lock_response != 0) { op_ret = object_lock_response; if (op_ret == -EACCES) { @@ -5156,15 +5155,14 @@ void RGWDeleteObj::execute(optional_yield y) } if (multipart_delete) { - if (!astate) { + if (state_loaded < 0) { op_ret = -ERR_NOT_SLO_MANIFEST; return; } - const auto slo_attr = astate->attrset.find(RGW_ATTR_SLO_MANIFEST); - - if (slo_attr != astate->attrset.end()) { - op_ret = handle_slo_manifest(slo_attr->second, y); + bufferlist slo_attr; + if (s->object->get_attr(RGW_ATTR_SLO_MANIFEST, slo_attr)) { + op_ret = handle_slo_manifest(slo_attr, y); if (op_ret < 0) { ldpp_dout(this, 0) << "ERROR: failed to handle slo manifest ret=" << op_ret << dendl; } @@ -5526,15 +5524,14 @@ void RGWCopyObj::execute(optional_yield y) uint64_t obj_size = 0; { // get src object size (cached in obj_ctx from verify_permission()) - RGWObjState* astate = nullptr; - op_ret = s->src_object->get_obj_state(this, &astate, s->yield, true); + op_ret = s->src_object->load_obj_state(this, s->yield, true); if (op_ret < 0) { return; } /* Check if the src object is cloud-tiered */ bufferlist bl; - if (astate->get_attr(RGW_ATTR_MANIFEST, bl)) { + if (s->src_object->get_attr(RGW_ATTR_MANIFEST, bl)) { RGWObjManifest m; try{ decode(m, bl); @@ -5553,15 +5550,15 @@ void RGWCopyObj::execute(optional_yield y) } } - obj_size = astate->size; + obj_size = s->src_object->get_obj_size(); if (!s->system_request) { // no quota enforcement for system requests - if (astate->accounted_size > static_cast(s->cct->_conf->rgw_max_put_size)) { + if (s->src_object->get_accounted_size() > static_cast(s->cct->_conf->rgw_max_put_size)) { op_ret = -ERR_TOO_LARGE; return; } // enforce quota against the destination bucket owner - op_ret = s->bucket->check_quota(this, quota, astate->accounted_size, y); + op_ret = s->bucket->check_quota(this, quota, s->src_object->get_accounted_size(), y); if (op_ret < 0) { return; } @@ -6713,9 +6710,9 @@ void RGWDeleteMultiObj::handle_individual_object(const rgw_obj_key& o, optional_ std::string etag; if (!rgw::sal::Object::empty(obj.get())) { - RGWObjState* astate = nullptr; + int state_loaded = -1; bool check_obj_lock = obj->have_instance() && bucket->get_info().obj_lock_enabled(); - const auto ret = obj->get_obj_state(this, &astate, y, true); + const auto ret = state_loaded = obj->load_obj_state(this, y, true); if (ret < 0) { if (ret == -ENOENT) { @@ -6727,13 +6724,13 @@ void RGWDeleteMultiObj::handle_individual_object(const rgw_obj_key& o, optional_ return; } } else { - obj_size = astate->size; - etag = astate->attrset[RGW_ATTR_ETAG].to_str(); + obj_size = obj->get_obj_size(); + etag = obj->get_attrs()[RGW_ATTR_ETAG].to_str(); } if (check_obj_lock) { - ceph_assert(astate); - int object_lock_response = verify_object_lock(this, astate->attrset, bypass_perm, bypass_governance_mode); + ceph_assert(state_loaded == 0); + int object_lock_response = verify_object_lock(this, obj->get_attrs(), bypass_perm, bypass_governance_mode); if (object_lock_response != 0) { send_partial_response(o, false, "", object_lock_response, formatter_flush_cond); return; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 0d1c3f0844e..171ace9162f 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -5293,14 +5293,10 @@ bool RGWHandler_REST_S3Website::web_dir() const { obj->set_atomic(); - RGWObjState* state = nullptr; - if (obj->get_obj_state(s, &state, s->yield) < 0) { + if (obj->load_obj_state(s, s->yield) < 0) { return false; } - if (! state->exists) { - return false; - } - return state->exists; + return obj->exists(); } int RGWHandler_REST_S3Website::init(rgw::sal::Driver* driver, req_state *s, diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index bde5925dfd1..fee38669b2d 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -2711,26 +2711,25 @@ bool RGWSwiftWebsiteHandler::is_web_dir() const obj->set_atomic(); obj->set_prefetch_data(); - RGWObjState* state = nullptr; - if (obj->get_obj_state(s, &state, s->yield, false)) { + if (obj->load_obj_state(s, s->yield, false)) { return false; } /* A nonexistent object cannot be a considered as a marker representing * the emulation of catalog in FS hierarchy. */ - if (! state->exists) { + if (! obj->exists()) { return false; } /* Decode the content type. */ std::string content_type; - get_contype_from_attrs(state->attrset, content_type); + get_contype_from_attrs(obj->get_attrs(), content_type); const auto& ws_conf = s->bucket->get_info().website_conf; const std::string subdir_marker = ws_conf.subdir_marker.empty() ? "application/directory" : ws_conf.subdir_marker; - return subdir_marker == content_type && state->size <= 1; + return subdir_marker == content_type && obj->get_obj_size() <= 1; } bool RGWSwiftWebsiteHandler::is_index_present(const std::string& index) const @@ -2740,14 +2739,13 @@ bool RGWSwiftWebsiteHandler::is_index_present(const std::string& index) const obj->set_atomic(); obj->set_prefetch_data(); - RGWObjState* state = nullptr; - if (obj->get_obj_state(s, &state, s->yield, false)) { + if (obj->load_obj_state(s, s->yield, false)) { return false; } /* A nonexistent object cannot be a considered as a viable index. We will * try to list the bucket or - if this is impossible - return an error. */ - return state->exists; + return obj->exists(); } int RGWSwiftWebsiteHandler::retarget_bucket(RGWOp* op, RGWOp** new_op) diff --git a/src/rgw/rgw_sal.cc b/src/rgw/rgw_sal.cc index f66c754420b..b02ad3657e9 100644 --- a/src/rgw/rgw_sal.cc +++ b/src/rgw/rgw_sal.cc @@ -67,41 +67,6 @@ extern rgw::sal::Driver* newD4NFilter(rgw::sal::Driver* next, boost::asio::io_co #endif } -RGWObjState::RGWObjState() { -} - -RGWObjState::~RGWObjState() { -} - -RGWObjState::RGWObjState(const RGWObjState& rhs) : obj (rhs.obj) { - is_atomic = rhs.is_atomic; - has_attrs = rhs.has_attrs; - exists = rhs.exists; - size = rhs.size; - accounted_size = rhs.accounted_size; - mtime = rhs.mtime; - epoch = rhs.epoch; - if (rhs.obj_tag.length()) { - obj_tag = rhs.obj_tag; - } - if (rhs.tail_tag.length()) { - tail_tag = rhs.tail_tag; - } - write_tag = rhs.write_tag; - fake_tag = rhs.fake_tag; - shadow_obj = rhs.shadow_obj; - has_data = rhs.has_data; - if (rhs.data.length()) { - data = rhs.data; - } - prefetch_data = rhs.prefetch_data; - keep_tail = rhs.keep_tail; - is_olh = rhs.is_olh; - objv_tracker = rhs.objv_tracker; - pg_ver = rhs.pg_ver; - compressed = rhs.compressed; -} - rgw::sal::Driver* DriverManager::init_storage_provider(const DoutPrefixProvider* dpp, CephContext* cct, const Config& cfg, diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index cd29e9c7428..51ec125039d 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -84,50 +84,6 @@ struct RGWClusterStat { uint64_t num_objects; }; -struct RGWObjState { - rgw_obj obj; - bool is_atomic{false}; - bool has_attrs{false}; - bool exists{false}; - uint64_t size{0}; //< size of raw object - uint64_t accounted_size{0}; //< size before compression, encryption - ceph::real_time mtime; - uint64_t epoch{0}; - bufferlist obj_tag; - bufferlist tail_tag; - std::string write_tag; - bool fake_tag{false}; - std::string shadow_obj; - bool has_data{false}; - bufferlist data; - bool prefetch_data{false}; - bool keep_tail{false}; - bool is_olh{false}; - bufferlist olh_tag; - uint64_t pg_ver{false}; - uint32_t zone_short_id{0}; - bool compressed{false}; - - /* important! don't forget to update copy constructor */ - - RGWObjVersionTracker objv_tracker; - - std::map attrset; - - RGWObjState(); - RGWObjState(const RGWObjState& rhs); - ~RGWObjState(); - - bool get_attr(std::string name, bufferlist& dest) { - auto iter = attrset.find(name); - if (iter != attrset.end()) { - dest = iter->second; - return true; - } - return false; - } -}; - /** * @defgroup RGWSAL RGW Store Abstraction Layer * @@ -1197,10 +1153,8 @@ class Object { /** Get the name of this object */ virtual const std::string &get_name() const = 0; - /** Get the object state for this object. Will be removed in the future */ - virtual int get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **state, optional_yield y, bool follow_olh = true) = 0; - /** Set the object state for this object */ - virtual void set_obj_state(RGWObjState& _state) = 0; + /** Load the object state for this object. */ + virtual int load_obj_state(const DoutPrefixProvider* dpp, optional_yield y, bool follow_olh = true) = 0; /** Set attributes for this object from the backing store. Attrs can be set or * deleted. @note the attribute APIs may be revisited in the future. */ virtual int set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, Attrs* delattrs, optional_yield y) = 0; @@ -1247,10 +1201,26 @@ class Object { virtual int set_attrs(Attrs a) = 0; /** Check to see if attributes are cached on this object */ virtual bool has_attrs(void) = 0; + /** Check to see if an attribute exists, and return it's value if it does */ + virtual bool get_attr(const std::string& name, bufferlist &dest) = 0; /** Get the cached modification time for this object */ virtual ceph::real_time get_mtime(void) const = 0; + /** Set the cached modification time for this object */ + virtual void set_mtime(ceph::real_time&) = 0; /** Get the cached size for this object */ virtual uint64_t get_obj_size(void) const = 0; + /** Get the cached accounted size for this object */ + virtual uint64_t get_accounted_size(void) const = 0; + /** Set the cached accounted size for this object */ + virtual void set_accounted_size(uint64_t) = 0; + /** Get the cached epoch for this object */ + virtual uint64_t get_epoch(void) const = 0; + /** Set the cached epoch for this object */ + virtual void set_epoch(uint64_t) = 0; + /** Get the cached short zone id for this object */ + virtual uint32_t get_short_zone_id(void) const = 0; + /** Set the cached short zone id for this object */ + virtual void set_short_zone_id(uint32_t) = 0; /** Get the bucket containing this object */ virtual Bucket* get_bucket(void) const = 0; /** Set the bucket containing this object */ @@ -1265,6 +1235,8 @@ class Object { virtual bool get_delete_marker(void) = 0; /** True if this object is stored in the extra data pool */ virtual bool get_in_extra_data(void) = 0; + /** True if this object exists in the store */ + virtual bool exists(void) = 0; /** Set the in_extra_data field */ virtual void set_in_extra_data(bool i) = 0; /** Helper to sanitize object size, offset, and end values */ diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc index 874935f1619..8c415feddc9 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -494,7 +494,7 @@ namespace rgw::sal { return std::make_unique(this); } - int DBObject::get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **pstate, optional_yield y, bool follow_olh) + int DBObject::load_obj_state(const DoutPrefixProvider* dpp, optional_yield y, bool follow_olh) { RGWObjState* astate; DB::Object op_target(store->getDB(), get_bucket()->get_info(), get_obj()); @@ -509,7 +509,6 @@ namespace rgw::sal { bool prefetch_data = state.prefetch_data; state = *astate; - *pstate = &state; state.obj = obj; state.is_atomic = is_atomic; diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h index eaa5fda5060..b542028e53e 100644 --- a/src/rgw/rgw_sal_dbstore.h +++ b/src/rgw/rgw_sal_dbstore.h @@ -541,7 +541,7 @@ protected: virtual RGWAccessControlPolicy& get_acl(void) override { return acls; } virtual int set_acl(const RGWAccessControlPolicy& acl) override { acls = acl; return 0; } - virtual int get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **state, optional_yield y, bool follow_olh = true) override; + virtual int load_obj_state(const DoutPrefixProvider* dpp, optional_yield y, bool follow_olh = true) override; virtual int set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, Attrs* delattrs, optional_yield y) override; virtual int get_obj_attrs(optional_yield y, const DoutPrefixProvider* dpp, rgw_obj* target_obj = NULL) override; virtual int modify_obj_attrs(const char* attr_name, bufferlist& attr_val, optional_yield y, const DoutPrefixProvider* dpp) override; diff --git a/src/rgw/rgw_sal_filter.cc b/src/rgw/rgw_sal_filter.cc index d6d51b20461..ce2844f244b 100644 --- a/src/rgw/rgw_sal_filter.cc +++ b/src/rgw/rgw_sal_filter.cc @@ -1044,10 +1044,9 @@ RGWAccessControlPolicy& FilterObject::get_acl() return next->get_acl(); } -int FilterObject::get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **pstate, - optional_yield y, bool follow_olh) -{ - return next->get_obj_state(dpp, pstate, y, follow_olh); +int FilterObject::load_obj_state(const DoutPrefixProvider *dpp, + optional_yield y, bool follow_olh) { + return next->load_obj_state(dpp, y, follow_olh); } int FilterObject::set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, diff --git a/src/rgw/rgw_sal_filter.h b/src/rgw/rgw_sal_filter.h index eaa8af2cb43..fe17ae9f3e8 100644 --- a/src/rgw/rgw_sal_filter.h +++ b/src/rgw/rgw_sal_filter.h @@ -756,9 +756,8 @@ public: virtual bool empty() const override { return next->empty(); } virtual const std::string &get_name() const override { return next->get_name(); } - virtual int get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **state, - optional_yield y, bool follow_olh = true) override; - virtual void set_obj_state(RGWObjState& _state) override { return next->set_obj_state(_state); } + virtual int load_obj_state(const DoutPrefixProvider *dpp, optional_yield y, + bool follow_olh = true) override; virtual int set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, Attrs* delattrs, optional_yield y) override; virtual int get_obj_attrs(optional_yield y, const DoutPrefixProvider* dpp, @@ -794,8 +793,16 @@ public: virtual const Attrs& get_attrs(void) const override { return next->get_attrs(); }; virtual int set_attrs(Attrs a) override { return next->set_attrs(a); }; virtual bool has_attrs(void) override { return next->has_attrs(); }; + virtual bool get_attr(const std::string& name, bufferlist &dest) override { return next->get_attr(name, dest); } virtual ceph::real_time get_mtime(void) const override { return next->get_mtime(); }; + virtual void set_mtime(ceph::real_time& mtime) override { return next->set_mtime(mtime); } virtual uint64_t get_obj_size(void) const override { return next->get_obj_size(); }; + virtual uint64_t get_accounted_size(void) const override { return next->get_accounted_size(); }; + virtual void set_accounted_size(uint64_t size) override { return next->set_accounted_size(size); } + virtual uint64_t get_epoch(void) const override { return next->get_epoch(); } + virtual void set_epoch(uint64_t epoch) override { return next->set_epoch(epoch); } + virtual uint32_t get_short_zone_id(void) const override { return next->get_short_zone_id(); } + virtual void set_short_zone_id(uint32_t id) override { return next->set_short_zone_id(id); } virtual Bucket* get_bucket(void) const override { return bucket; }; virtual void set_bucket(Bucket* b) override; virtual std::string get_hash_source(void) override { return next->get_hash_source(); }; @@ -803,6 +810,7 @@ public: virtual std::string get_oid(void) const override { return next->get_oid(); }; virtual bool get_delete_marker(void) override { return next->get_delete_marker(); }; virtual bool get_in_extra_data(void) override { return next->get_in_extra_data(); }; + virtual bool exists(void) override { return next->exists(); }; virtual void set_in_extra_data(bool i) override { return next->set_in_extra_data(i); }; int range_to_ofs(uint64_t obj_size, int64_t &ofs, int64_t &end) { return next->range_to_ofs(obj_size, ofs, end); diff --git a/src/rgw/rgw_sal_store.h b/src/rgw/rgw_sal_store.h index 8bfff802526..d37f63e5c81 100644 --- a/src/rgw/rgw_sal_store.h +++ b/src/rgw/rgw_sal_store.h @@ -17,6 +17,81 @@ #include "rgw_sal.h" +/** + * @brief State for a StoreObject + */ +struct RGWObjState { + rgw_obj obj; + bool is_atomic{false}; + bool has_attrs{false}; + bool exists{false}; + uint64_t size{0}; //< size of raw object + uint64_t accounted_size{0}; //< size before compression, encryption + ceph::real_time mtime; + uint64_t epoch{0}; + bufferlist obj_tag; + bufferlist tail_tag; + std::string write_tag; + bool fake_tag{false}; + std::string shadow_obj; + bool has_data{false}; + bufferlist data; + bool prefetch_data{false}; + bool keep_tail{false}; + bool is_olh{false}; + bufferlist olh_tag; + uint64_t pg_ver{false}; + uint32_t zone_short_id{0}; + bool compressed{false}; + + /* important! don't forget to update copy constructor */ + + RGWObjVersionTracker objv_tracker; + + std::map attrset; + + RGWObjState() {}; + RGWObjState(const RGWObjState &rhs) : obj(rhs.obj) { + is_atomic = rhs.is_atomic; + has_attrs = rhs.has_attrs; + exists = rhs.exists; + size = rhs.size; + accounted_size = rhs.accounted_size; + mtime = rhs.mtime; + epoch = rhs.epoch; + if (rhs.obj_tag.length()) { + obj_tag = rhs.obj_tag; + } + if (rhs.tail_tag.length()) { + tail_tag = rhs.tail_tag; + } + write_tag = rhs.write_tag; + fake_tag = rhs.fake_tag; + shadow_obj = rhs.shadow_obj; + has_data = rhs.has_data; + if (rhs.data.length()) { + data = rhs.data; + } + prefetch_data = rhs.prefetch_data; + keep_tail = rhs.keep_tail; + is_olh = rhs.is_olh; + objv_tracker = rhs.objv_tracker; + pg_ver = rhs.pg_ver; + compressed = rhs.compressed; + } + + ~RGWObjState() {}; + + bool get_attr(std::string name, bufferlist& dest) { + auto iter = attrset.find(name); + if (iter != attrset.end()) { + dest = iter->second; + return true; + } + return false; + } +}; + namespace rgw { namespace sal { class StoreDriver : public Driver { @@ -221,15 +296,29 @@ class StoreObject : public Object { virtual bool empty() const override { return state.obj.empty(); } virtual const std::string &get_name() const override { return state.obj.key.name; } - virtual void set_obj_state(RGWObjState& _state) override { - state = _state; - } virtual Attrs& get_attrs(void) override { return state.attrset; } virtual const Attrs& get_attrs(void) const override { return state.attrset; } virtual int set_attrs(Attrs a) override { state.attrset = a; state.has_attrs = true; return 0; } virtual bool has_attrs(void) override { return state.has_attrs; } + virtual bool get_attr(const std::string& name, bufferlist &dest) override { + if (!has_attrs()) + return false; + auto iter = state.attrset.find(name); + if (iter != state.attrset.end()) { + dest = iter->second; + return true; + } + return false; + } virtual ceph::real_time get_mtime(void) const override { return state.mtime; } + virtual void set_mtime(ceph::real_time& mtime) override { state.mtime = mtime; } virtual uint64_t get_obj_size(void) const override { return state.size; } + virtual uint64_t get_accounted_size(void) const override { return state.accounted_size; } + virtual void set_accounted_size(uint64_t size) override { state.accounted_size = size; } + virtual uint64_t get_epoch(void) const override { return state.epoch; } + virtual void set_epoch(uint64_t epoch) override { state.epoch = epoch; } + virtual uint32_t get_short_zone_id(void) const override { return state.zone_short_id; } + virtual void set_short_zone_id(uint32_t id) override { state.zone_short_id = id; } virtual Bucket* get_bucket(void) const override { return bucket; } virtual void set_bucket(Bucket* b) override { bucket = b; state.obj.bucket = b->get_key(); } virtual std::string get_hash_source(void) override { return state.obj.index_hash_source; } @@ -237,6 +326,7 @@ class StoreObject : public Object { virtual std::string get_oid(void) const override { return state.obj.key.get_oid(); } virtual bool get_delete_marker(void) override { return delete_marker; } virtual bool get_in_extra_data(void) override { return state.obj.is_in_extra_data(); } + virtual bool exists(void) override { return state.exists; } virtual void set_in_extra_data(bool i) override { state.obj.set_in_extra_data(i); } int range_to_ofs(uint64_t obj_size, int64_t &ofs, int64_t &end); virtual void set_obj_size(uint64_t s) override { state.size = s; } -- 2.39.5