return ret;
}
+int RGWMetadataManager::prepare_mutate(RGWRados *store,
+ rgw_pool& pool, const string& oid,
+ const real_time& mtime,
+ RGWObjVersionTracker *objv_tracker,
+ RGWMetadataHandler::sync_type_t sync_mode)
+{
+ bufferlist bl;
+ real_time orig_mtime;
+ RGWObjectCtx obj_ctx(store);
+ int ret = rgw_get_system_obj(store, obj_ctx, pool, oid,
+ bl, objv_tracker, &orig_mtime,
+ nullptr, nullptr);
+ if (ret < 0 && ret != -ENOENT) {
+ return ret;
+ }
+ if (ret != -ENOENT &&
+ !RGWMetadataHandler::check_versions(objv_tracker->read_version, orig_mtime,
+ objv_tracker->write_version, mtime, sync_mode)) {
+ return STATUS_NO_APPLY;
+ }
+
+ return 0;
+}
+
int RGWMetadataManager::remove(string& metadata_key)
{
RGWMetadataHandler *handler;
*
* @return true if the update should proceed, false otherwise.
*/
- bool check_versions(const obj_version& ondisk, const real_time& ondisk_time,
- const obj_version& incoming, const real_time& incoming_time,
- sync_type_t sync_mode) {
+ static bool check_versions(const obj_version& ondisk, const real_time& ondisk_time,
+ const obj_version& incoming, const real_time& incoming_time,
+ sync_type_t sync_mode) {
switch (sync_mode) {
case APPLY_UPDATES:
if ((ondisk.tag != incoming.tag) ||
RGWObjVersionTracker *objv_tracker, real_time mtime,
map<string, bufferlist> *pattrs);
int remove_from_heap(RGWMetadataHandler *handler, const string& key, RGWObjVersionTracker *objv_tracker);
+ int prepare_mutate(RGWRados *store, rgw_pool& pool, const string& oid,
+ const real_time& mtime,
+ RGWObjVersionTracker *objv_tracker,
+ RGWMetadataHandler::sync_type_t sync_mode);
+
public:
RGWMetadataManager(CephContext *_cct, RGWRados *_store);
~RGWMetadataManager();
int register_handler(RGWMetadataHandler *handler);
template <typename F>
- int operate(RGWMetadataHandler *handler, const string& key,
- RGWObjVersionTracker *objv_tracker, RGWMDLogStatus op_type,
- F&& f);
+ int mutate(RGWMetadataHandler *handler, const string& key,
+ const ceph::real_time& mtime, RGWObjVersionTracker *objv_tracker,
+ RGWMDLogStatus op_type,
+ RGWMetadataHandler::sync_type_t sync_mode,
+ F&& f);
RGWMetadataHandler *get_handler(const string& type);
};
template <typename F>
-int RGWMetadataManager::operate(RGWMetadataHandler *handler, const string& key,
- RGWObjVersionTracker *objv_tracker, RGWMDLogStatus op_type,
- F&& f)
+int RGWMetadataManager::mutate(RGWMetadataHandler *handler, const string& key,
+ const ceph::real_time& mtime, RGWObjVersionTracker *objv_tracker,
+ RGWMDLogStatus op_type,
+ RGWMetadataHandler::sync_type_t sync_mode,
+ F&& f)
{
- string section;
- RGWMetadataLogData log_data;
- int ret = pre_modify(handler, section, key, log_data, objv_tracker, MDLOG_STATUS_WRITE);
- if (ret < 0)
- return ret;
-
string oid;
rgw_pool pool;
handler->get_pool_and_oid(store, key, pool, oid);
+ int ret = prepare_mutate(store, pool, oid, mtime, objv_tracker, sync_mode);
+ if (ret < 0 ||
+ ret == STATUS_NO_APPLY) {
+ return ret;
+ }
+
+ string section;
+ RGWMetadataLogData log_data;
+ ret = pre_modify(handler, section, key, log_data, objv_tracker, MDLOG_STATUS_WRITE);
+ if (ret < 0) {
+ return ret;
+ }
+
ret = std::forward<F>(f)();
/* cascading ret into post_modify() */
return -EINVAL;
}
- bufferlist bl;
- real_time orig_mtime;
- RGWObjectCtx obj_ctx(store);
- int ret = rgw_get_system_obj(store, obj_ctx, store->get_zone_params().otp_pool,
- entry, bl, &objv_tracker, &orig_mtime, nullptr, nullptr);
- if (ret < 0 && ret != -ENOENT) {
+ int ret = store->meta_mgr->mutate(this, entry, mtime, &objv_tracker,
+ MDLOG_STATUS_WRITE, sync_mode,
+ [&] {
+ return store->set_mfa(entry, devices, true, &objv_tracker, mtime);
+ });
+ if (ret < 0) {
return ret;
}
- if (ret != -ENOENT &&
- !check_versions(objv_tracker.read_version, orig_mtime,
- objv_tracker.write_version, mtime, sync_mode)) {
- return STATUS_NO_APPLY;
- }
- store->meta_mgr->operate(this, entry, &objv_tracker, MDLOG_STATUS_WRITE, [&] {
- return store->set_mfa(entry, devices, true, &objv_tracker);
- });
return STATUS_APPLIED;
}
}
int RGWRados::set_mfa(const string& oid, const list<rados::cls::otp::otp_info_t>& entries,
- bool reset_obj, RGWObjVersionTracker *objv_tracker)
+ bool reset_obj, RGWObjVersionTracker *objv_tracker,
+ const real_time& mtime)
{
rgw_raw_obj obj(get_zone_params().otp_pool, oid);
rgw_rados_ref ref;
op.create(false);
}
ot.prepare_op_for_write(&op);
+ struct timespec mtime_ts = real_clock::to_timespec(mtime);
+ op.mtime2(&mtime_ts);
rados::cls::otp::OTP::set(&op, entries);
r = ref.ioctx.operate(ref.oid, &op);
if (r < 0) {