diff --git a/src/rgw/driver/sfs/bucket.cc b/src/rgw/driver/sfs/bucket.cc index d81eb09099ae5..4049ee7b2e901 100644 --- a/src/rgw/driver/sfs/bucket.cc +++ b/src/rgw/driver/sfs/bucket.cc @@ -71,11 +71,6 @@ void SFSBucket::Meta::decode_json(JSONObj* obj) { JSONDecoder::decode_json("info", info, obj); } -std::unique_ptr SFSBucket::_get_object(sfs::ObjectRef obj) { - rgw_obj_key key(obj->name, obj->instance); - return make_unique(this->store, key, this, bucket); -} - std::unique_ptr SFSBucket::get_object(const rgw_obj_key& key) { ldout(store->ceph_context(), SFS_LOG_DEBUG) << "bucket::" << __func__ << ": key : " << key << dendl; @@ -88,7 +83,7 @@ std::unique_ptr SFSBucket::get_object(const rgw_obj_key& key) { // specific version" operation. // Return the object with the same key as it was requested. objref->instance = key.instance; - return _get_object(objref); + return make_unique(this->store, key, this, bucket); } catch (const sfs::UnknownObjectException& _) { ldout(store->ceph_context(), SFS_LOG_VERBOSE) << "unable to find key " << key << " in bucket " << bucket->get_name() diff --git a/src/rgw/driver/sfs/bucket.h b/src/rgw/driver/sfs/bucket.h index 7e98f5926d5bc..2c0270e6974b3 100644 --- a/src/rgw/driver/sfs/bucket.h +++ b/src/rgw/driver/sfs/bucket.h @@ -52,8 +52,6 @@ class SFSBucket : public StoreBucket { void write_meta(const DoutPrefixProvider* dpp); - std::unique_ptr _get_object(sfs::ObjectRef obj); - /// Verify params passed to list() int verify_list_params( const DoutPrefixProvider* dpp, const ListParams& params, int max diff --git a/src/rgw/driver/sfs/multipart.cc b/src/rgw/driver/sfs/multipart.cc index c6a9f396943ce..7d1b4d7aae6e2 100644 --- a/src/rgw/driver/sfs/multipart.cc +++ b/src/rgw/driver/sfs/multipart.cc @@ -57,18 +57,12 @@ SFSMultipartUploadV2::SFSMultipartUploadV2( std::unique_ptr SFSMultipartUploadV2::get_meta_obj() { rgw_obj_key key(meta_str, string(), RGW_OBJ_NS_MULTIPART); - auto mmo = - std::make_unique(store, key, bucket, bucketref); - sfs::sqlite::SQLiteMultipart mpdb(store->db_conn); auto mp = mpdb.get_multipart(upload_id); ceph_assert(mp.has_value()); - mmo->set_attrs(mp->attrs); - // TODO(jecluis): this needs to be fixed once we get rid of the objref - mmo->set_object_ref( - std::shared_ptr(sfs::Object::create_from_obj_key(key)) + return std::make_unique( + store, key, bucket, bucketref, mp->attrs ); - return mmo; } int SFSMultipartUploadV2::init( @@ -431,7 +425,7 @@ int SFSMultipartUploadV2::complete( // new object, or a new version, and move the file to its location as if we // were writing directly to it. - ObjectRef objref; + std::unique_ptr objref; try { objref = bucketref->create_version(target_obj->get_key()); } catch (const std::system_error& e) { diff --git a/src/rgw/driver/sfs/multipart.h b/src/rgw/driver/sfs/multipart.h index dda5ae9ef7b36..ca59cdcb8daff 100644 --- a/src/rgw/driver/sfs/multipart.h +++ b/src/rgw/driver/sfs/multipart.h @@ -36,14 +36,54 @@ class SFStore; * bits that are relevant for the SAL layer's expected path. * * For reference, check 'rgw_op.cc', RGWCompleteMultipart::execute(). + * + * Note that during MP uploads, before completing them, the object is + * actually a promise of a future object. To make this promise + * accessible to certain queries (e.g get_attr) initialize the + * underlying objref from MP data rather than object / versioned + * object data. */ struct SFSMultipartMetaObject : public rgw::sal::SFSObject { - SFSMultipartMetaObject(SFSMultipartMetaObject&) = default; + SFSMultipartMetaObject(SFSMultipartMetaObject&) = delete; SFSMultipartMetaObject( rgw::sal::SFStore* _st, const rgw_obj_key& _k, rgw::sal::Bucket* _b, - BucketRef _bucket + BucketRef _bucket, const rgw::sal::Attrs& attrs ) - : rgw::sal::SFSObject(_st, _k, _b, _bucket, false) {} + : rgw::sal::SFSObject(_st, _k, _b, _bucket, false) { + // Note: objref points to a object that does not actually exists. + objref.reset(sfs::Object::create_from_obj_key(_k)); + objref->update_attrs(attrs); + } + + struct SFSMetaObjReadOp : public ReadOp { + private: + const sfs::Object& obj; + + public: + SFSMetaObjReadOp() = delete; + SFSMetaObjReadOp(const sfs::Object& _obj) : obj(_obj) {} + virtual int prepare(optional_yield, const DoutPrefixProvider*) override { + return 0; + } + virtual int + read(int64_t, int64_t, bufferlist&, optional_yield, const DoutPrefixProvider*) + override { + return -ENOTSUP; + } + virtual int iterate( + const DoutPrefixProvider*, int64_t, int64_t, RGWGetDataCB*, + optional_yield + ) override { + return -ENOTSUP; + } + virtual int get_attr( + const DoutPrefixProvider*, const char* name, bufferlist& dest, + optional_yield + ) override { + return obj.get_attr(name, dest); + } + const std::string get_cls_name() { return "mp_meta_obj_read"; } + }; struct SFSMetaObjDeleteOp : public DeleteOp { SFSMetaObjDeleteOp() = default; @@ -55,9 +95,7 @@ struct SFSMultipartMetaObject : public rgw::sal::SFSObject { const std::string get_cls_name() { return "mp_meta_obj_delete"; } }; - virtual std::unique_ptr clone() override { - return std::unique_ptr(new SFSMultipartMetaObject{*this}); - } + virtual std::unique_ptr clone() override { return nullptr; } SFSMultipartMetaObject& operator=(const SFSMultipartMetaObject&) = delete; virtual std::unique_ptr get_delete_op() override { @@ -70,6 +108,10 @@ struct SFSMultipartMetaObject : public rgw::sal::SFSObject { ) override { return 0; } + + virtual std::unique_ptr get_read_op() override { + return std::make_unique(*objref); + } }; class SFSMultipartPartV2 : public StoreMultipartPart { diff --git a/src/rgw/driver/sfs/object.cc b/src/rgw/driver/sfs/object.cc index 6a55441622c4e..43620982cb6c4 100644 --- a/src/rgw/driver/sfs/object.cc +++ b/src/rgw/driver/sfs/object.cc @@ -29,19 +29,8 @@ using namespace std; namespace rgw::sal { -SFSObject::SFSReadOp::SFSReadOp(SFSObject* _source) : source(_source) { - /* - This initialization code was originally into prepare() but that - was not sufficient to cover all cases. - There are pieces of SAL code that are calling get_*() methods - but they don't call prepare(). - In those cases the SFSReadOp is not properly initialized and those - calls are going to fail. - */ - // read op needs to retrieve also the version_id from the db - source->refresh_meta(true); - objref = source->get_object_ref(); -} +SFSObject::SFSReadOp::SFSReadOp(const SFSObject& _source) + : source(_source), objref(_source.get_object_ref()) {} // Handle conditional GET params. If-Match, If-None-Match, // If-Modified-Since, If-UnModified-Since. Return 0 if we are neutral. @@ -52,8 +41,8 @@ int SFSObject::SFSReadOp::handle_conditionals(const DoutPrefixProvider* dpp !params.unmod_ptr) { return 0; } - const std::string etag = objref->get_meta().etag; - const auto mtime = objref->get_meta().mtime; + const std::string etag = objref.get_meta().etag; + const auto mtime = objref.get_meta().mtime; int result = 0; if (params.if_match) { @@ -114,13 +103,13 @@ int SFSObject::SFSReadOp::handle_conditionals(const DoutPrefixProvider* dpp int SFSObject::SFSReadOp::prepare( optional_yield /*y*/, const DoutPrefixProvider* dpp ) { - if (!objref || objref->deleted) { + if (objref.deleted) { // at this point, we don't have an objectref because // the object does not exist. return -ENOENT; } - objdata = source->store->get_data_path() / objref->get_storage_path(); + objdata = source.store->get_data_path() / objref.get_storage_path(); if (!std::filesystem::exists(objdata)) { lsfs_verb(dpp) << "object data not found at " << objdata << dendl; return -ENOENT; @@ -130,15 +119,15 @@ int SFSObject::SFSReadOp::prepare( << fmt::format( "bucket:{} obj:{} size:{} versionid:{} " "conditionals:(ifmatch:{} ifnomatch:{} ifmod:{} ifunmod:{})", - source->bucket->get_name(), source->get_name(), - source->get_obj_size(), source->get_instance(), + source.bucket->get_name(), source.get_name(), + source.get_obj_size(), source.get_instance(), fmt::ptr(params.if_match), fmt::ptr(params.if_nomatch), fmt::ptr(params.mod_ptr), fmt::ptr(params.unmod_ptr) ) << dendl; if (params.lastmod) { - *params.lastmod = source->get_mtime(); + *params.lastmod = source.get_mtime(); } return handle_conditionals(dpp); } @@ -147,10 +136,10 @@ int SFSObject::SFSReadOp::get_attr( const DoutPrefixProvider* /*dpp*/, const char* name, bufferlist& dest, optional_yield /*y*/ ) { - if (!objref || objref->deleted) { + if (objref.deleted) { return -ENOENT; } - if (!objref->get_attr(name, dest)) { + if (!objref.get_attr(name, dest)) { return -ENODATA; } return 0; @@ -163,9 +152,9 @@ int SFSObject::SFSReadOp::read( ) { // TODO bounds check, etc. const auto len = end + 1 - ofs; - lsfs_debug(dpp) << "bucket: " << source->bucket->get_name() - << ", obj: " << source->get_name() - << ", size: " << source->get_obj_size() << ", offset: " << ofs + lsfs_debug(dpp) << "bucket: " << source.bucket->get_name() + << ", obj: " << source.get_name() + << ", size: " << source.get_obj_size() << ", offset: " << ofs << ", end: " << end << ", len: " << len << dendl; ceph_assert(std::filesystem::exists(objdata)); @@ -187,9 +176,9 @@ int SFSObject::SFSReadOp::iterate( ) { // TODO bounds check, etc. const auto len = end + 1 - ofs; - lsfs_debug(dpp) << "bucket: " << source->bucket->get_name() - << ", obj: " << source->get_name() - << ", size: " << source->get_obj_size() << ", offset: " << ofs + lsfs_debug(dpp) << "bucket: " << source.bucket->get_name() + << ", obj: " << source.get_name() + << ", size: " << source.get_obj_size() << ", offset: " << ofs << ", end: " << end << ", len: " << len << dendl; ceph_assert(std::filesystem::exists(objdata)); @@ -243,7 +232,7 @@ int SFSObject::SFSDeleteOp::delete_obj( auto version_id = source->get_instance(); std::string delete_marker_version_id; - if (source->objref) { + if (source->state.exists) { bucketref->delete_object( *source->objref, source->get_key(), source->bucket->versioning_enabled(), delete_marker_version_id @@ -335,7 +324,7 @@ int SFSObject::copy_object( return -ERR_INTERNAL_ERROR; } - const sfs::ObjectRef dstref = + const std::unique_ptr dstref = dst_bucket_ref->create_version(dst_object->get_key()); if (!dstref) { ::close(src_fd); @@ -643,24 +632,27 @@ void SFSObject::refresh_meta(bool update_version_id_from_metadata) { try { objref = bucketref->get(rgw_obj_key(get_name(), get_instance())); } catch (sfs::UnknownObjectException& e) { - // object probably not created yet? + objref = std::unique_ptr(sfs::Object::create_from_obj_key( + rgw_obj_key(get_name(), get_instance()) + )); + objref->deleted = true; + state.exists = false; + // object probably not created yet - return a deleted placeholder return; } - _refresh_meta_from_object(objref, update_version_id_from_metadata); + _refresh_meta_from_object(*objref, update_version_id_from_metadata); } void SFSObject::_refresh_meta_from_object( - sfs::ObjectRef obj_to_refresh, bool update_version_id_from_metadata + const sfs::Object& obj_to_refresh, bool update_version_id_from_metadata ) { - ceph_assert(obj_to_refresh); - // fill values from objref - set_obj_size(obj_to_refresh->get_meta().size); - set_attrs(obj_to_refresh->get_attrs()); - state.accounted_size = obj_to_refresh->get_meta().size; - state.mtime = obj_to_refresh->get_meta().mtime; + set_obj_size(obj_to_refresh.get_meta().size); + set_attrs(obj_to_refresh.get_attrs()); + state.accounted_size = obj_to_refresh.get_meta().size; + state.mtime = obj_to_refresh.get_meta().mtime; state.exists = true; if (update_version_id_from_metadata) { - set_instance(obj_to_refresh->instance); + set_instance(obj_to_refresh.instance); } } diff --git a/src/rgw/driver/sfs/object.h b/src/rgw/driver/sfs/object.h index 774115f731b51..9fcec599b2bf8 100644 --- a/src/rgw/driver/sfs/object.h +++ b/src/rgw/driver/sfs/object.h @@ -30,32 +30,35 @@ class SFStore; class SFSObject : public StoreObject { private: - SFStore* store; RGWAccessControlPolicy acls; - sfs::BucketRef bucketref; - sfs::ObjectRef objref; protected: - SFSObject(SFSObject&) = default; + SFStore* store; + sfs::BucketRef bucketref; + std::unique_ptr objref; + + SFSObject(SFSObject&) = delete; void _refresh_meta_from_object( - sfs::ObjectRef obj_to_refresh, + const sfs::Object& obj_to_refresh, bool update_version_id_from_metadata = false ); + const sfs::Object& get_object_ref() const { return *objref; } + public: /** * reads an object's contents. */ struct SFSReadOp : public ReadOp { private: - SFSObject* source; - sfs::ObjectRef objref; + const SFSObject& source; + const sfs::Object& objref; std::filesystem::path objdata; int handle_conditionals(const DoutPrefixProvider* dpp) const; public: - SFSReadOp(SFSObject* _source); + SFSReadOp(const SFSObject& _source); virtual int prepare(optional_yield y, const DoutPrefixProvider* dpp) override; @@ -107,19 +110,11 @@ class SFSObject : public StoreObject { refresh_meta(); } } - SFSObject( - SFStore* _st, const rgw_obj_key& _k, Bucket* _b, - sfs::BucketRef _bucketref, sfs::ObjectRef _objref - ) - : StoreObject(_k, _b), - store(_st), - bucketref(_bucketref), - objref(_objref) { - _refresh_meta_from_object(objref); - } virtual std::unique_ptr clone() override { - return std::unique_ptr(new SFSObject{*this}); + return std::unique_ptr( + new SFSObject(store, get_key(), get_bucket(), bucketref, true) + ); } virtual int delete_object( @@ -194,7 +189,8 @@ class SFSObject : public StoreObject { * Obtain a Read Operation. */ virtual std::unique_ptr get_read_op() override { - return std::make_unique(this); + this->refresh_meta(true); + return std::make_unique(*this); } /** * Obtain a Delete Operation. @@ -239,10 +235,6 @@ class SFSObject : public StoreObject { bool get_attr(const std::string& name, bufferlist& dest); - sfs::ObjectRef get_object_ref() { return objref; } - - void set_object_ref(sfs::ObjectRef objref) { this->objref = objref; } - // Refresh metadata from db. // Also retrieves version_id when specified. // There are situations (like delete operations) in which we don't want to diff --git a/src/rgw/driver/sfs/sqlite/sqlite_versioned_objects.cc b/src/rgw/driver/sfs/sqlite/sqlite_versioned_objects.cc index f0e848c778ba5..2b398aa295ef2 100644 --- a/src/rgw/driver/sfs/sqlite/sqlite_versioned_objects.cc +++ b/src/rgw/driver/sfs/sqlite/sqlite_versioned_objects.cc @@ -294,41 +294,10 @@ SQLiteVersionedObjects::get_last_versioned_object( return ret_value; } -std::optional -SQLiteVersionedObjects::delete_version_and_get_previous_transact( - const uuid_d& object_id, uint id +void SQLiteVersionedObjects::delete_version(uint version_id ) const { - try { - auto storage = conn->get_storage(); - auto transaction = storage->transaction_guard(); - std::optional ret_value = std::nullopt; - storage->remove(id); - if (storage->changes()) { - // get the last version of the object now - auto last_version_select = storage->get_all( - where( - is_equal(&DBVersionedObject::object_id, object_id) and - is_not_equal( - &DBVersionedObject::object_state, ObjectState::DELETED - ) - ), - multi_order_by( - order_by(&DBVersionedObject::commit_time).desc(), - order_by(&DBVersionedObject::id).desc() - ), - limit(1) - ); - if (!last_version_select.empty()) { - ret_value = last_version_select[0]; - } - transaction.commit(); - } - return ret_value; - } catch (const std::system_error& e) { - // throw exception (will be caught later in the sfs logic) - // TODO revisit this when error handling is defined - throw(e); - } + auto storage = conn->get_storage(); + storage->remove(version_id); } uint SQLiteVersionedObjects::add_delete_marker_transact( diff --git a/src/rgw/driver/sfs/sqlite/sqlite_versioned_objects.h b/src/rgw/driver/sfs/sqlite/sqlite_versioned_objects.h index 41db7f9af1de8..d23ab7e0081ae 100644 --- a/src/rgw/driver/sfs/sqlite/sqlite_versioned_objects.h +++ b/src/rgw/driver/sfs/sqlite/sqlite_versioned_objects.h @@ -63,8 +63,8 @@ class SQLiteVersionedObjects { const uuid_d& object_id, bool filter_deleted = true ) const; - std::optional delete_version_and_get_previous_transact( - const uuid_d& object_id, uint id + void delete_version( + uint id ) const; std::optional create_new_versioned_object_transact( diff --git a/src/rgw/driver/sfs/types.cc b/src/rgw/driver/sfs/types.cc index 3f4bee8207259..8444ad0f2b10d 100644 --- a/src/rgw/driver/sfs/types.cc +++ b/src/rgw/driver/sfs/types.cc @@ -42,12 +42,6 @@ std::string generate_new_version_id(CephContext* ceph_context) { Object::Object(const rgw_obj_key& _key, const uuid_d& _uuid) : name(_key.name), instance(_key.instance), path(_uuid), deleted(false) {} -Object* Object::create_for_immediate_deletion(const sqlite::DBObject& object) { - Object* result = new Object(object.name, object.uuid); - result->deleted = true; - return result; -} - void Object::delete_version_data( SFStore* store, const uuid_d& uuid, uint version_id ) { @@ -56,15 +50,6 @@ void Object::delete_version_data( result->delete_object_data(store); } -Object* Object::create_for_query( - const std::string& name, const uuid_d& uuid, bool deleted, uint version_id -) { - Object* result = new Object(name, uuid); - result->deleted = deleted; - result->version_id = version_id; - return result; -} - Object* Object::create_for_testing(const std::string& name) { Object* result = new Object(name, UUIDPath::create().get_uuid()); return result; @@ -92,30 +77,6 @@ Object* Object::create_from_db_version( return result; } -Object* Object::create_from_db_version( - const std::string& object_name, const sqlite::DBObjectsListItem& version -) { - Object* result = new Object( - rgw_obj_key(object_name, sqlite::get_version_id(version)), - sqlite::get_uuid(version) - ); - result->deleted = - (sqlite::get_version_type(version) == VersionType::DELETE_MARKER); - result->version_id = sqlite::get_id(version); - result->meta = { - .size = sqlite::get_size(version), - .etag = sqlite::get_etag(version), - .mtime = sqlite::get_mtime(version), - .delete_at = sqlite::get_delete_time(version)}; - result->attrs = sqlite::get_attrs(version); - return result; -} - -Object* Object::create_for_multipart(const std::string& name) { - Object* result = new Object(name, UUIDPath::create().get_uuid()); - return result; -} - Object* Object::create_commit_delete_marker( const rgw_obj_key& key, SFStore* store, const std::string& bucket_id ) { @@ -281,14 +242,14 @@ void Object::delete_object_data(SFStore* store) const { std::filesystem::remove(folder_path, delete_folder_error); } -ObjectRef Bucket::create_version(const rgw_obj_key& key) const { +std::unique_ptr Bucket::create_version(const rgw_obj_key& key) const { // even if a specific version was not asked we generate one // non-versioned bucket objects will also have a version_id auto version_id = key.instance; if (version_id.empty()) { version_id = generate_new_version_id(store->ceph_context()); } - ObjectRef result; + std::unique_ptr result; sqlite::SQLiteVersionedObjects objs_versions(store->db_conn); // create objects in a transaction. // That way threads trying to create the same object in parallel will be @@ -302,7 +263,7 @@ ObjectRef Bucket::create_version(const rgw_obj_key& key) const { return result; } -ObjectRef Bucket::get(const rgw_obj_key& key) const { +std::unique_ptr Bucket::get(const rgw_obj_key& key) const { auto maybe_result = Object::try_fetch_from_database( store, key.name, info.bucket.bucket_id, key.instance, get_info().versioning_enabled() @@ -312,24 +273,7 @@ ObjectRef Bucket::get(const rgw_obj_key& key) const { throw UnknownObjectException(); } - return std::shared_ptr(maybe_result); -} - -std::vector Bucket::get_all() const { - std::vector result; - sqlite::SQLiteVersionedObjects db_versioned_objs(store->db_conn); - // get the list of objects and its last version (filters deleted versions) - // if an object has all versions deleted it is also filtered - auto objects = - db_versioned_objs.list_last_versioned_objects(info.bucket.bucket_id); - for (const auto& db_obj : objects) { - if (sqlite::get_object_state(db_obj) == ObjectState::COMMITTED) { - result.push_back(std::shared_ptr( - Object::create_from_db_version(sqlite::get_name(db_obj), db_obj) - )); - } - } - return result; + return std::unique_ptr(maybe_result); } bool Bucket::delete_object( @@ -366,7 +310,7 @@ bool Bucket::delete_object( std::string Bucket::create_non_existing_object_delete_marker( const rgw_obj_key& key ) const { - auto obj = std::shared_ptr( + auto obj = std::unique_ptr( Object::create_commit_delete_marker(key, store, info.bucket.bucket_id) ); // create the delete marker @@ -394,9 +338,7 @@ bool Bucket::_undelete_object( // only remove the delete marker if the requested version id is the last one if (!key.instance.empty() && (key.instance == last_version.version_id)) { // remove the delete marker and get the previous version in a transaction - sqlite_versioned_objects.delete_version_and_get_previous_transact( - last_version.object_id, last_version.id - ); + sqlite_versioned_objects.delete_version(last_version.id); } } return true; @@ -408,6 +350,11 @@ bool Bucket::_delete_object_non_versioned( ) const { auto version_to_delete = db_versioned_objs.get_last_versioned_object(obj.path.get_uuid()); + if (!version_to_delete.has_value()) { + // if there is no latest version to delete, assume that we are + // already deleted and do nothing + return true; + } return _delete_object_version(db_versioned_objs, *version_to_delete); } diff --git a/src/rgw/driver/sfs/types.h b/src/rgw/driver/sfs/types.h index 9b2b8ba459851..947e72914d0e5 100644 --- a/src/rgw/driver/sfs/types.h +++ b/src/rgw/driver/sfs/types.h @@ -69,28 +69,15 @@ class Object { path(UUIDPath::create()), deleted(false) {} - static Object* _get_object( - SFStore* store, const std::string& bucket_id, const rgw_obj_key& key - ); - public: - static Object* create_for_immediate_deletion(const sqlite::DBObject& object); static void delete_version_data( SFStore* store, const uuid_d& uuid, uint version_id ); - static Object* create_for_query( - const std::string& name, const uuid_d& uuid, bool deleted, uint version_id - ); static Object* create_for_testing(const std::string& name); static Object* create_from_obj_key(const rgw_obj_key& key); static Object* create_from_db_version( const std::string& object_name, const sqlite::DBVersionedObject& version ); - static Object* create_from_db_version( - const std::string& object_name, const sqlite::DBObjectsListItem& version - ); - static Object* create_for_multipart(const std::string& name); - static Object* create_commit_delete_marker( const rgw_obj_key& key, SFStore* store, const std::string& bucket_id ); @@ -127,8 +114,6 @@ class Object { void delete_object_data(SFStore* store) const; }; -using ObjectRef = std::shared_ptr; - class Bucket { CephContext* cct; rgw::sal::SFStore* store; @@ -207,12 +192,10 @@ class Bucket { ceph::real_time get_mtime() const { return mtime; } /// Create object version for key - ObjectRef create_version(const rgw_obj_key& key) const; + std::unique_ptr create_version(const rgw_obj_key& key) const; /// Get existing object by key. Throws if it doesn't exist. - ObjectRef get(const rgw_obj_key& key) const; - /// Get copy of all objects that are committed and not deleted - std::vector get_all() const; + std::unique_ptr get(const rgw_obj_key& key) const; /// S3 delete object operation: delete version or create tombstone. /// If a delete marker was added, it returns the new version id generated for diff --git a/src/rgw/driver/sfs/writer.h b/src/rgw/driver/sfs/writer.h index 2a2516f68f5f4..24dbac07a4084 100644 --- a/src/rgw/driver/sfs/writer.h +++ b/src/rgw/driver/sfs/writer.h @@ -30,7 +30,7 @@ class SFSAtomicWriter : public StoreWriter { rgw::sal::SFStore* store; SFSObject obj; sfs::BucketRef bucketref; - sfs::ObjectRef objref; + std::unique_ptr objref; const rgw_user& owner; const rgw_placement_rule* placement_rule; uint64_t olh_epoch; diff --git a/src/test/rgw/sfs/test_rgw_sfs_concurrency.cc b/src/test/rgw/sfs/test_rgw_sfs_concurrency.cc index ff98d728e80c1..b55f648856b11 100644 --- a/src/test/rgw/sfs/test_rgw_sfs_concurrency.cc +++ b/src/test/rgw/sfs/test_rgw_sfs_concurrency.cc @@ -67,7 +67,7 @@ class TestSFSConcurrency std::unique_ptr store; BucketRef bucket; - ObjectRef predef_object; + std::unique_ptr predef_object; sqlite::DBVersionedObject predef_db_object; TestSFSConcurrency() @@ -291,7 +291,7 @@ INSTANTIATE_TEST_SUITE_P( "create_new_version__unversioned", [](const SFSConcurrencyFixture& fixture) { std::string version = gen_rand_alphanumeric(fixture.cct, 23); - ObjectRef obj; + std::unique_ptr obj; while (!obj) { // create version is ok to return null if it did not // succeed. To test metadata_finish we need to retry.. @@ -307,7 +307,7 @@ INSTANTIATE_TEST_SUITE_P( "create_new_version__versioned", [](const SFSConcurrencyFixture& fixture) { std::string version = gen_rand_alphanumeric(fixture.cct, 23); - ObjectRef obj; + std::unique_ptr obj; while (!obj) { // create version is ok to return null if it did not // succeed. To test metadata_finish we need to retry.. diff --git a/src/test/rgw/sfs/test_rgw_sfs_object_state_machine.cc b/src/test/rgw/sfs/test_rgw_sfs_object_state_machine.cc index 24bd7fc550a37..101cbf0fb5401 100644 --- a/src/test/rgw/sfs/test_rgw_sfs_object_state_machine.cc +++ b/src/test/rgw/sfs/test_rgw_sfs_object_state_machine.cc @@ -86,37 +86,37 @@ class TestSFSObjectStateMachine : public ::testing::Test { fs::path getDBFullPath() const { return getDBFullPath(getTestDir()); } sqlite::DBConnRef dbconn() { return store->db_conn; } sqlite::StorageRef storage() { return dbconn()->get_storage(); } - ObjectState database_object_state(ObjectRef obj) { + ObjectState database_object_state(const Object& obj) { return storage() ->select( &sqlite::DBVersionedObject::object_state, sqlite_orm::where(sqlite_orm::is_equal( - &sqlite::DBVersionedObject::id, obj->version_id + &sqlite::DBVersionedObject::id, obj.version_id )) ) .back(); } - VersionType database_version_type(ObjectRef obj) { + VersionType database_version_type(const Object& obj) { return storage() ->select( &sqlite::DBVersionedObject::version_type, sqlite_orm::where(sqlite_orm::is_equal( - &sqlite::DBVersionedObject::id, obj->version_id + &sqlite::DBVersionedObject::id, obj.version_id )) ) .back(); } - int database_number_of_versions(ObjectRef obj) { + int database_number_of_versions(const Object& obj) { return storage() ->select( sqlite_orm::count(), sqlite_orm::where(sqlite_orm::is_equal( - &sqlite::DBVersionedObject::object_id, obj->path.get_uuid() + &sqlite::DBVersionedObject::object_id, obj.path.get_uuid() )) ) .back(); } - auto database_get_versions_as_id_type_state(ObjectRef obj) { + auto database_get_versions_as_id_type_state(const Object& obj) { return storage()->select( sqlite_orm::columns( &sqlite::DBVersionedObject::version_id, @@ -124,7 +124,7 @@ class TestSFSObjectStateMachine : public ::testing::Test { &sqlite::DBVersionedObject::object_state ), sqlite_orm::where(sqlite_orm::is_equal( - &sqlite::DBVersionedObject::object_id, obj->path.get_uuid() + &sqlite::DBVersionedObject::object_id, obj.path.get_uuid() )), sqlite_orm::order_by(&sqlite::DBVersionedObject::id).asc() ); @@ -133,9 +133,9 @@ class TestSFSObjectStateMachine : public ::testing::Test { TEST_F(TestSFSObjectStateMachine, object_start_in_open) { const auto object = bucket->create_version(rgw_obj_key("foo", "bar")); - EXPECT_EQ(database_object_state(object), ObjectState::OPEN); - EXPECT_EQ(database_version_type(object), VersionType::REGULAR); - EXPECT_EQ(database_number_of_versions(object), 1); + EXPECT_EQ(database_object_state(*object), ObjectState::OPEN); + EXPECT_EQ(database_version_type(*object), VersionType::REGULAR); + EXPECT_EQ(database_number_of_versions(*object), 1); } TEST_F(TestSFSObjectStateMachine, multiple_open_versions_are_ok) { @@ -144,15 +144,15 @@ TEST_F(TestSFSObjectStateMachine, multiple_open_versions_are_ok) { const auto object = bucket->create_version( rgw_obj_key("name", fmt::format("instance_{}", i)) ); - ASSERT_EQ(database_object_state(object), ObjectState::OPEN); - ASSERT_EQ(database_number_of_versions(object), i + 1); + ASSERT_EQ(database_object_state(*object), ObjectState::OPEN); + ASSERT_EQ(database_number_of_versions(*object), i + 1); } } TEST_F(TestSFSObjectStateMachine, non_committed_objects_are_invisible_to_get) { const auto object = bucket->create_version(rgw_obj_key("foo", "bar")); EXPECT_THROW(bucket->get(rgw_obj_key("foo", "bar")), UnknownObjectException); - EXPECT_EQ(database_number_of_versions(object), 1); + EXPECT_EQ(database_number_of_versions(*object), 1); } TEST_F( @@ -163,8 +163,8 @@ TEST_F( std::string unused; ASSERT_TRUE(bucket->delete_object(*object, rgw_obj_key("foo"), false, unused) ); - EXPECT_EQ(database_object_state(object), ObjectState::DELETED); - EXPECT_EQ(database_version_type(object), VersionType::REGULAR); + EXPECT_EQ(database_object_state(*object), ObjectState::DELETED); + EXPECT_EQ(database_version_type(*object), VersionType::REGULAR); } TEST_F( @@ -175,9 +175,9 @@ TEST_F( std::string unused; ASSERT_TRUE(bucket->delete_object(*object, rgw_obj_key("foo"), false, unused) ); - ASSERT_EQ(database_object_state(object), ObjectState::DELETED); + ASSERT_EQ(database_object_state(*object), ObjectState::DELETED); EXPECT_FALSE(object->metadata_finish(store.get(), false)); - EXPECT_EQ(database_object_state(object), ObjectState::DELETED); + EXPECT_EQ(database_object_state(*object), ObjectState::DELETED); } TEST_F( @@ -188,102 +188,102 @@ TEST_F( ASSERT_TRUE( bucket->delete_object(*object, rgw_obj_key("foo", "bar"), false, unused) ); - ASSERT_EQ(database_object_state(object), ObjectState::DELETED); + ASSERT_EQ(database_object_state(*object), ObjectState::DELETED); EXPECT_FALSE(object->metadata_finish(store.get(), true)); - EXPECT_EQ(database_object_state(object), ObjectState::DELETED); + EXPECT_EQ(database_object_state(*object), ObjectState::DELETED); } TEST_F( TestSFSObjectStateMachine, unversioned__commit_deletes_all_committed_versions ) { - const std::array objects = { + const std::array, 3> objects = { bucket->create_version(rgw_obj_key("foo", "version1")), bucket->create_version(rgw_obj_key("foo", "version2")), bucket->create_version(rgw_obj_key("foo", "version3")), }; - ASSERT_EQ(database_object_state(objects[0]), ObjectState::OPEN); - ASSERT_EQ(database_object_state(objects[1]), ObjectState::OPEN); - ASSERT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[0]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[1]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); EXPECT_TRUE(objects[0]->metadata_finish(store.get(), false)); - EXPECT_EQ(database_object_state(objects[0]), ObjectState::COMMITTED); - EXPECT_EQ(database_object_state(objects[1]), ObjectState::OPEN); - EXPECT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + EXPECT_EQ(database_object_state(*objects[0]), ObjectState::COMMITTED); + EXPECT_EQ(database_object_state(*objects[1]), ObjectState::OPEN); + EXPECT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); } TEST_F(TestSFSObjectStateMachine, unversioned__last_committer_wins) { - const std::array objects = { + const std::array, 3> objects = { bucket->create_version(rgw_obj_key("foo", "version1")), bucket->create_version(rgw_obj_key("foo", "version2")), bucket->create_version(rgw_obj_key("foo", "version3")), }; - ASSERT_EQ(database_object_state(objects[0]), ObjectState::OPEN); - ASSERT_EQ(database_object_state(objects[1]), ObjectState::OPEN); - ASSERT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[0]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[1]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); EXPECT_TRUE(objects[0]->metadata_finish(store.get(), false)); - EXPECT_EQ(database_object_state(objects[0]), ObjectState::COMMITTED); - EXPECT_EQ(database_object_state(objects[1]), ObjectState::OPEN); - EXPECT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + EXPECT_EQ(database_object_state(*objects[0]), ObjectState::COMMITTED); + EXPECT_EQ(database_object_state(*objects[1]), ObjectState::OPEN); + EXPECT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); EXPECT_TRUE(objects[1]->metadata_finish(store.get(), false)); - EXPECT_EQ(database_object_state(objects[0]), ObjectState::DELETED); - EXPECT_EQ(database_object_state(objects[1]), ObjectState::COMMITTED); - EXPECT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + EXPECT_EQ(database_object_state(*objects[0]), ObjectState::DELETED); + EXPECT_EQ(database_object_state(*objects[1]), ObjectState::COMMITTED); + EXPECT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); EXPECT_TRUE(objects[2]->metadata_finish(store.get(), false)); - EXPECT_EQ(database_object_state(objects[0]), ObjectState::DELETED); - EXPECT_EQ(database_object_state(objects[1]), ObjectState::DELETED); - EXPECT_EQ(database_object_state(objects[2]), ObjectState::COMMITTED); + EXPECT_EQ(database_object_state(*objects[0]), ObjectState::DELETED); + EXPECT_EQ(database_object_state(*objects[1]), ObjectState::DELETED); + EXPECT_EQ(database_object_state(*objects[2]), ObjectState::COMMITTED); } TEST_F( TestSFSObjectStateMachine, unversioned__commit_on_deleted_by_another_commit_fails ) { - const std::array objects = { + const std::array, 3> objects = { bucket->create_version(rgw_obj_key("foo", "version1")), bucket->create_version(rgw_obj_key("foo", "version2")), bucket->create_version(rgw_obj_key("foo", "version3")), }; ASSERT_TRUE(objects[0]->metadata_finish(store.get(), false)); - ASSERT_EQ(database_object_state(objects[0]), ObjectState::COMMITTED); - ASSERT_EQ(database_object_state(objects[1]), ObjectState::OPEN); - ASSERT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[0]), ObjectState::COMMITTED); + ASSERT_EQ(database_object_state(*objects[1]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); EXPECT_TRUE(objects[1]->metadata_finish(store.get(), false)); - EXPECT_EQ(database_object_state(objects[0]), ObjectState::DELETED); - EXPECT_EQ(database_object_state(objects[1]), ObjectState::COMMITTED); - EXPECT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + EXPECT_EQ(database_object_state(*objects[0]), ObjectState::DELETED); + EXPECT_EQ(database_object_state(*objects[1]), ObjectState::COMMITTED); + EXPECT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); EXPECT_FALSE(objects[0]->metadata_finish(store.get(), false)); - ASSERT_EQ(database_object_state(objects[0]), ObjectState::DELETED); - ASSERT_EQ(database_object_state(objects[1]), ObjectState::COMMITTED); - ASSERT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[0]), ObjectState::DELETED); + ASSERT_EQ(database_object_state(*objects[1]), ObjectState::COMMITTED); + ASSERT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); } TEST_F( TestSFSObjectStateMachine, versioned__commit_does_not_change_any_other_version_state ) { - const std::array objects = { + const std::array, 3> objects = { bucket->create_version(rgw_obj_key("foo", "version1")), bucket->create_version(rgw_obj_key("foo", "version2")), bucket->create_version(rgw_obj_key("foo", "version3"))}; - ASSERT_EQ(database_object_state(objects[0]), ObjectState::OPEN); - ASSERT_EQ(database_object_state(objects[1]), ObjectState::OPEN); - ASSERT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[0]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[1]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); EXPECT_TRUE(objects[0]->metadata_finish(store.get(), true)); - EXPECT_EQ(database_object_state(objects[0]), ObjectState::COMMITTED); - EXPECT_EQ(database_object_state(objects[1]), ObjectState::OPEN); - EXPECT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + EXPECT_EQ(database_object_state(*objects[0]), ObjectState::COMMITTED); + EXPECT_EQ(database_object_state(*objects[1]), ObjectState::OPEN); + EXPECT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); EXPECT_TRUE(objects[2]->metadata_finish(store.get(), true)); - EXPECT_EQ(database_object_state(objects[0]), ObjectState::COMMITTED); - EXPECT_EQ(database_object_state(objects[1]), ObjectState::OPEN); - EXPECT_EQ(database_object_state(objects[2]), ObjectState::COMMITTED); + EXPECT_EQ(database_object_state(*objects[0]), ObjectState::COMMITTED); + EXPECT_EQ(database_object_state(*objects[1]), ObjectState::OPEN); + EXPECT_EQ(database_object_state(*objects[2]), ObjectState::COMMITTED); } TEST_F( @@ -291,28 +291,28 @@ TEST_F( versioned__delete_does_not_change_any_other_version_state ) { std::string unused; - const std::array objects = { + const std::array, 3> objects = { bucket->create_version(rgw_obj_key("foo", "version1")), bucket->create_version(rgw_obj_key("foo", "version2")), bucket->create_version(rgw_obj_key("foo", "version3"))}; ASSERT_TRUE(objects[0]->metadata_finish(store.get(), true)); - ASSERT_EQ(database_object_state(objects[0]), ObjectState::COMMITTED); - ASSERT_EQ(database_object_state(objects[1]), ObjectState::OPEN); - ASSERT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[0]), ObjectState::COMMITTED); + ASSERT_EQ(database_object_state(*objects[1]), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); EXPECT_TRUE(bucket->delete_object( *objects[1], rgw_obj_key("foo", "version2"), true, unused )); - EXPECT_EQ(database_object_state(objects[0]), ObjectState::COMMITTED); - EXPECT_EQ(database_object_state(objects[1]), ObjectState::DELETED); - EXPECT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + EXPECT_EQ(database_object_state(*objects[0]), ObjectState::COMMITTED); + EXPECT_EQ(database_object_state(*objects[1]), ObjectState::DELETED); + EXPECT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); EXPECT_TRUE(bucket->delete_object( *objects[0], rgw_obj_key("foo", "version1"), true, unused )); - EXPECT_EQ(database_object_state(objects[0]), ObjectState::DELETED); - EXPECT_EQ(database_object_state(objects[1]), ObjectState::DELETED); - EXPECT_EQ(database_object_state(objects[2]), ObjectState::OPEN); + EXPECT_EQ(database_object_state(*objects[0]), ObjectState::DELETED); + EXPECT_EQ(database_object_state(*objects[1]), ObjectState::DELETED); + EXPECT_EQ(database_object_state(*objects[2]), ObjectState::OPEN); } TEST_F( @@ -324,9 +324,9 @@ TEST_F( std::string unused; EXPECT_TRUE(bucket->delete_object(*object, rgw_obj_key("foo"), false, unused) ); - EXPECT_EQ(database_object_state(object), ObjectState::DELETED); - EXPECT_EQ(database_version_type(object), VersionType::REGULAR); - EXPECT_EQ(database_number_of_versions(object), 1); + EXPECT_EQ(database_object_state(*object), ObjectState::DELETED); + EXPECT_EQ(database_version_type(*object), VersionType::REGULAR); + EXPECT_EQ(database_number_of_versions(*object), 1); } class TestSFSVersionedDeleteMarkerTests @@ -345,14 +345,14 @@ TEST_P( default: break; } - ASSERT_EQ(database_object_state(object), initial_state); - ASSERT_EQ(database_version_type(object), VersionType::REGULAR); + ASSERT_EQ(database_object_state(*object), initial_state); + ASSERT_EQ(database_version_type(*object), VersionType::REGULAR); std::string delete_marker_id; ASSERT_TRUE( bucket->delete_object(*object, rgw_obj_key("foo"), true, delete_marker_id) ); - const auto versions = database_get_versions_as_id_type_state(object); + const auto versions = database_get_versions_as_id_type_state(*object); EXPECT_FALSE(delete_marker_id.empty()); ASSERT_EQ(versions.size(), 2); EXPECT_EQ(std::get<0>(versions[0]), "VERSION"); @@ -374,24 +374,18 @@ TEST_F( ) { const auto object = bucket->create_version(rgw_obj_key("foo", "VERSION")); object->metadata_finish(store.get(), false); - ASSERT_EQ(database_object_state(object), ObjectState::COMMITTED); - ASSERT_EQ(database_version_type(object), VersionType::REGULAR); + ASSERT_EQ(database_object_state(*object), ObjectState::COMMITTED); + ASSERT_EQ(database_version_type(*object), VersionType::REGULAR); std::string delete_marker_id; EXPECT_TRUE(bucket->delete_object( *object, rgw_obj_key("foo", "VERSION"), true, delete_marker_id )); - EXPECT_EQ(database_object_state(object), ObjectState::DELETED); - EXPECT_EQ(database_version_type(object), VersionType::REGULAR); + EXPECT_EQ(database_object_state(*object), ObjectState::DELETED); + EXPECT_EQ(database_version_type(*object), VersionType::REGULAR); EXPECT_NE(delete_marker_id, object->instance); EXPECT_EQ("", delete_marker_id); - EXPECT_EQ(database_number_of_versions(object), 1); -} - -TEST_F(TestSFSObjectStateMachine, non_committed_are_invisible_to_get_all) { - const auto object = bucket->create_version(rgw_obj_key("foo", "bar")); - const auto all = bucket->get_all(); - ASSERT_EQ(all.size(), 0); + EXPECT_EQ(database_number_of_versions(*object), 1); } TEST_F(TestSFSObjectStateMachine, metadata_finish_makes_visible_to_get) { @@ -402,16 +396,8 @@ TEST_F(TestSFSObjectStateMachine, metadata_finish_makes_visible_to_get) { EXPECT_EQ(object->instance, obj_gotten->instance); } -TEST_F(TestSFSObjectStateMachine, metadata_finish_makes_visible_to_get_all) { - auto object = bucket->create_version(rgw_obj_key("foo", "bar")); - object->metadata_finish(store.get(), false); - const auto all = bucket->get_all(); - EXPECT_EQ(all.size(), 1); - EXPECT_EQ(all.front()->name, "foo"); -} - TEST_F(TestSFSObjectStateMachine, flush_attrs_does_not_commit) { const auto object = bucket->create_version(rgw_obj_key("foo", "bar")); object->metadata_flush_attrs(store.get()); - ASSERT_EQ(database_object_state(object), ObjectState::OPEN); + ASSERT_EQ(database_object_state(*object), ObjectState::OPEN); } diff --git a/src/test/rgw/sfs/test_rgw_sfs_sqlite_versioned_objects.cc b/src/test/rgw/sfs/test_rgw_sfs_sqlite_versioned_objects.cc index 908ca529db49b..6b33949930ce2 100644 --- a/src/test/rgw/sfs/test_rgw_sfs_sqlite_versioned_objects.cc +++ b/src/test/rgw/sfs/test_rgw_sfs_sqlite_versioned_objects.cc @@ -912,53 +912,6 @@ TEST_F(TestSFSSQLiteVersionedObjects, TestFilterDeleted) { ASSERT_EQ(5, last_version->id); } -TEST_F(TestSFSSQLiteVersionedObjects, TestDeleteLastAndGetPrevious) { - auto ceph_context = std::make_shared(CEPH_ENTITY_TYPE_CLIENT); - ceph_context->_conf.set_val("rgw_sfs_data_path", getTestDir()); - ceph_context->_log->start(); - - EXPECT_FALSE(fs::exists(getDBFullPath())); - DBConnRef conn = std::make_shared(ceph_context.get()); - - auto db_versioned_objects = std::make_shared(conn); - - // Create the object, we need it because of foreign key constrains - createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn - ); - - // create 3 versions (last one is a delete marker) - auto object = createTestVersionedObject(1, TEST_OBJECT_ID, "1"); - object.object_state = rgw::sal::sfs::ObjectState::COMMITTED; - EXPECT_EQ(1, db_versioned_objects->insert_versioned_object(object)); - object.version_id = "test_version_id_2"; - EXPECT_EQ(2, db_versioned_objects->insert_versioned_object(object)); - object.version_id = "test_version_id_3"; - object.version_type = rgw::sal::sfs::VersionType::DELETE_MARKER; - EXPECT_EQ(3, db_versioned_objects->insert_versioned_object(object)); - - auto last_version_now = - db_versioned_objects->delete_version_and_get_previous_transact( - object.object_id, 3 - ); - ASSERT_TRUE(last_version_now.has_value()); - ASSERT_EQ(2, last_version_now->id); - ASSERT_EQ("test_version_id_2", last_version_now->version_id); - - auto delete_version_doesnt_exist = - db_versioned_objects->delete_version_and_get_previous_transact( - object.object_id, 1999 - ); - ASSERT_FALSE(delete_version_doesnt_exist.has_value()); - - uuid_d object_id; - object_id.parse(TEST_OBJECT_ID.c_str()); - last_version_now = db_versioned_objects->get_last_versioned_object(object_id); - ASSERT_TRUE(last_version_now.has_value()); - ASSERT_EQ(2, last_version_now->id); - ASSERT_EQ("test_version_id_2", last_version_now->version_id); -} - TEST_F(TestSFSSQLiteVersionedObjects, TestGetByBucketAndObjectName) { auto ceph_context = std::make_shared(CEPH_ENTITY_TYPE_CLIENT); ceph_context->_conf.set_val("rgw_sfs_data_path", getTestDir()); diff --git a/src/test/rgw/sfs/test_rgw_sfs_wal_checkpoint.cc b/src/test/rgw/sfs/test_rgw_sfs_wal_checkpoint.cc index 8495be007ef89..6072551cfdc50 100644 --- a/src/test/rgw/sfs/test_rgw_sfs_wal_checkpoint.cc +++ b/src/test/rgw/sfs/test_rgw_sfs_wal_checkpoint.cc @@ -85,7 +85,7 @@ class TestSFSWALCheckpoint : public ::testing::Test { for (size_t i = 0; i < num_threads; ++i) { std::thread t([&, i]() { for (size_t j = 0; j < num_objects; ++j) { - ObjectRef obj; + std::unique_ptr obj; while (!obj) { obj = bucket->create_version(rgw_obj_key( "object-" + std::to_string(i) + "-" + std::to_string(j)