auto& ioctx = ref.ioctx;
tracepoint(rgw_rados, operate_enter, req_id.c_str());
- r = rgw_rados_operate(rctx.dpp, ref.ioctx, ref.obj.oid, &op, rctx.y, 0, &trace);
+ r = rgw_rados_operate(rctx.dpp, ref.ioctx, ref.obj.oid, &op, rctx.y, 0, &trace, &epoch);
tracepoint(rgw_rados, operate_exit, req_id.c_str());
if (r < 0) { /* we can expect to get -ECANCELED if object was replaced under,
or -ENOENT if was removed, or -EEXIST if it did not exist
goto done_cancel;
}
- epoch = ioctx.get_last_version();
poolid = ioctx.get_id();
r = target->complete_atomic_modification(rctx.dpp, rctx.y);
}
auto& ioctx = ref.ioctx;
- r = rgw_rados_operate(dpp, ioctx, ref.obj.oid, &op, y);
+ version_t epoch = 0;
+ r = rgw_rados_operate(dpp, ioctx, ref.obj.oid, &op, y, 0, nullptr, &epoch);
/* raced with another operation, object state is indeterminate */
const bool need_invalidate = (r == -ECANCELED);
tombstone_entry entry{*state};
obj_tombstone_cache->add(obj, entry);
}
- r = index_op.complete_del(dpp, poolid, ioctx.get_last_version(), state->mtime, params.remove_objs, y, log_op);
+ r = index_op.complete_del(dpp, poolid, epoch, state->mtime, params.remove_objs, y, log_op);
int ret = target->complete_atomic_modification(dpp, y);
if (ret < 0) {
struct timespec mtime_ts = real_clock::to_timespec(mtime);
op.mtime2(&mtime_ts);
auto& ioctx = ref.ioctx;
- r = rgw_rados_operate(dpp, ioctx, ref.obj.oid, &op, y);
+ version_t epoch = 0;
+ r = rgw_rados_operate(dpp, ioctx, ref.obj.oid, &op, y, 0, nullptr, &epoch);
if (state) {
if (r >= 0) {
ACLOwner owner;
iter != state->attrset.end()) {
storage_class = rgw_bl_str(iter->second);
}
- uint64_t epoch = ioctx.get_last_version();
int64_t poolid = ioctx.get_id();
r = index_op.complete(dpp, poolid, epoch, state->size, state->accounted_size,
mtime, etag, content_type, storage_class, owner,
}
bufferlist outbl;
- r = rgw_rados_operate(dpp, ref.ioctx, ref.obj.oid, &op, &outbl, y);
-
- if (epoch) {
- *epoch = ref.ioctx.get_last_version();
- }
-
+ r = rgw_rados_operate(dpp, ref.ioctx, ref.obj.oid, &op, &outbl, y, 0, nullptr, epoch);
if (r < 0)
return r;
num_entries << " total entries" << dendl;
auto& ioctx = index_pool;
+
+ // XXX: check_disk_state() relies on ioctx.get_last_version() but that
+ // returns 0 because CLSRGWIssueBucketList doesn't make any synchonous calls
+ rgw_bucket_entry_ver index_ver;
+ index_ver.pool = ioctx.get_id();
+
std::map<int, rgw_cls_list_ret> shard_list_results;
cls_rgw_obj_key start_after_key(start_after.name, start_after.instance);
r = CLSRGWIssueBucketList(ioctx, start_after_key, prefix, delimiter,
/* there are uncommitted ops. We need to check the current
* state, and if the tags are old we need to do clean-up as
* well. */
- librados::IoCtx sub_ctx;
- sub_ctx.dup(ioctx);
ldout_bitx(bitx, dpp, 20) << "INFO: " << __func__ <<
" calling check_disk_state bucket=" << bucket_info.bucket <<
" entry=" << dirent.key << dendl_bitx;
- r = check_disk_state(dpp, sub_ctx, bucket_info, dirent, dirent,
+ r = check_disk_state(dpp, bucket_info, index_ver, dirent, dirent,
updates[tracker.oid_name], y);
if (r < 0 && r != -ENOENT) {
ldpp_dout(dpp, 0) << __func__ <<
}
}
+ rgw_bucket_entry_ver index_ver;
+ index_ver.pool = ioctx.get_id();
+
uint32_t count = 0u;
std::map<std::string, bufferlist> updates;
rgw_obj_index_key last_added_entry;
cls_rgw_bucket_list_op(op, marker, prefix, empty_delimiter,
num_entries,
list_versions, &result);
- r = rgw_rados_operate(dpp, ioctx, oid, &op, nullptr, y);
+ r = rgw_rados_operate(dpp, ioctx, oid, &op, nullptr, y, 0, nullptr, &index_ver.epoch);
if (r < 0) {
ldpp_dout(dpp, 0) << "ERROR: " << __func__ <<
": error in rgw_rados_operate (bucket list op), r=" << r << dendl;
force_check) {
/* there are uncommitted ops. We need to check the current state,
* and if the tags are old we need to do cleanup as well. */
- librados::IoCtx sub_ctx;
- sub_ctx.dup(ioctx);
ldout_bitx(bitx, dpp, 20) << "INFO: " << __func__ <<
": calling check_disk_state bucket=" << bucket_info.bucket <<
" entry=" << dirent.key << dendl_bitx;
- r = check_disk_state(dpp, sub_ctx, bucket_info, dirent, dirent, updates[oid], y);
+ r = check_disk_state(dpp, bucket_info, index_ver, dirent, dirent, updates[oid], y);
if (r < 0 && r != -ENOENT) {
ldpp_dout(dpp, 0) << "ERROR: " << __func__ <<
": error in check_disk_state, r=" << r << dendl;
}
int RGWRados::check_disk_state(const DoutPrefixProvider *dpp,
- librados::IoCtx io_ctx,
RGWBucketInfo& bucket_info,
+ const rgw_bucket_entry_ver& index_ver,
rgw_bucket_dir_entry& list_state,
rgw_bucket_dir_entry& object,
bufferlist& suggested_updates,
ldpp_dout(dpp, 0) << "WARNING: generated locator (" << loc << ") is different from listed locator (" << list_state.locator << ")" << dendl;
}
- io_ctx.locator_set_key(list_state.locator);
-
RGWObjState *astate = NULL;
RGWObjManifest *manifest = nullptr;
RGWObjectCtx octx(this->driver);
}
// encode a suggested removal of that key
- list_state.ver.epoch = io_ctx.get_last_version();
- list_state.ver.pool = io_ctx.get_id();
+ list_state.ver = index_ver;
ldout_bitx(bitx, dpp, 10) << "INFO: " << __func__ << ": encoding remove of " << list_state.key << " on suggested_updates" << dendl_bitx;
cls_rgw_encode_suggestion(CEPH_RGW_REMOVE | suggest_flag, list_state, suggested_updates);
return -ENOENT;
int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
librados::ObjectReadOperation *op, bufferlist* pbl,
- optional_yield y, int flags, const jspan_context* trace_info)
+ optional_yield y, int flags, const jspan_context* trace_info,
+ version_t* pver)
{
// given a yield_context, call async_operate() to yield the coroutine instead
// of blocking
if (y) {
auto& yield = y.get_yield_context();
boost::system::error_code ec;
- auto bl = librados::async_operate(
+ auto [ver, bl] = librados::async_operate(
yield, ioctx, oid, op, flags, trace_info, yield[ec]);
if (pbl) {
*pbl = std::move(bl);
}
+ if (pver) {
+ *pver = ver;
+ }
return -ec.value();
}
maybe_warn_about_blocking(dpp);
- return ioctx.operate(oid, op, nullptr, flags);
+ int r = ioctx.operate(oid, op, nullptr, flags);
+ if (pver) {
+ *pver = ioctx.get_last_version();
+ }
+ return r;
}
int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
librados::ObjectWriteOperation *op, optional_yield y,
- int flags, const jspan_context* trace_info)
+ int flags, const jspan_context* trace_info, version_t* pver)
{
if (y) {
auto& yield = y.get_yield_context();
boost::system::error_code ec;
- librados::async_operate(yield, ioctx, oid, op, flags, trace_info, yield[ec]);
+ version_t ver = librados::async_operate(yield, ioctx, oid, op, flags,
+ trace_info, yield[ec]);
+ if (pver) {
+ *pver = ver;
+ }
return -ec.value();
}
maybe_warn_about_blocking(dpp);
- return ioctx.operate(oid, op, flags, trace_info);
+ int r = ioctx.operate(oid, op, flags, trace_info);
+ if (pver) {
+ *pver = ioctx.get_last_version();
+ }
+ return r;
}
int rgw_rados_notify(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
if (y) {
auto& yield = y.get_yield_context();
boost::system::error_code ec;
- auto reply = librados::async_notify(yield, ioctx, oid,
- bl, timeout_ms, yield[ec]);
+ auto [ver, reply] = librados::async_notify(yield, ioctx, oid,
+ bl, timeout_ms, yield[ec]);
if (pbl) {
*pbl = std::move(reply);
}