Skip to content

Commit 7769bdb

Browse files
committed
rgw/rados: rgw_rados_operate() takes version_t*
instead of calling ioctx.get_last_version() after a rados operation, callers now pass version_t* as an output parameter. in the null_yield case, that version is assigned to ioctx.get_last_version() as normal. in the async case, we get the version out of librados::async_operate()'s return value Fixes: https://tracker.ceph.com/issues/63935 Signed-off-by: Casey Bodley <[email protected]>
1 parent 5cc7cf4 commit 7769bdb

File tree

6 files changed

+57
-42
lines changed

6 files changed

+57
-42
lines changed

src/rgw/driver/rados/rgw_rados.cc

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3247,7 +3247,7 @@ int RGWRados::Object::Write::_do_write_meta(uint64_t size, uint64_t accounted_si
32473247
auto& ioctx = ref.ioctx;
32483248

32493249
tracepoint(rgw_rados, operate_enter, req_id.c_str());
3250-
r = rgw_rados_operate(rctx.dpp, ref.ioctx, ref.obj.oid, &op, rctx.y, 0, &trace);
3250+
r = rgw_rados_operate(rctx.dpp, ref.ioctx, ref.obj.oid, &op, rctx.y, 0, &trace, &epoch);
32513251
tracepoint(rgw_rados, operate_exit, req_id.c_str());
32523252
if (r < 0) { /* we can expect to get -ECANCELED if object was replaced under,
32533253
or -ENOENT if was removed, or -EEXIST if it did not exist
@@ -3259,7 +3259,6 @@ int RGWRados::Object::Write::_do_write_meta(uint64_t size, uint64_t accounted_si
32593259
goto done_cancel;
32603260
}
32613261

3262-
epoch = ioctx.get_last_version();
32633262
poolid = ioctx.get_id();
32643263

32653264
r = target->complete_atomic_modification(rctx.dpp, rctx.y);
@@ -5870,7 +5869,8 @@ int RGWRados::Object::Delete::delete_obj(optional_yield y, const DoutPrefixProvi
58705869
}
58715870

58725871
auto& ioctx = ref.ioctx;
5873-
r = rgw_rados_operate(dpp, ioctx, ref.obj.oid, &op, y);
5872+
version_t epoch = 0;
5873+
r = rgw_rados_operate(dpp, ioctx, ref.obj.oid, &op, y, 0, nullptr, &epoch);
58745874

58755875
/* raced with another operation, object state is indeterminate */
58765876
const bool need_invalidate = (r == -ECANCELED);
@@ -5882,7 +5882,7 @@ int RGWRados::Object::Delete::delete_obj(optional_yield y, const DoutPrefixProvi
58825882
tombstone_entry entry{*state};
58835883
obj_tombstone_cache->add(obj, entry);
58845884
}
5885-
r = index_op.complete_del(dpp, poolid, ioctx.get_last_version(), state->mtime, params.remove_objs, y, log_op);
5885+
r = index_op.complete_del(dpp, poolid, epoch, state->mtime, params.remove_objs, y, log_op);
58865886

58875887
int ret = target->complete_atomic_modification(dpp, y);
58885888
if (ret < 0) {
@@ -6603,7 +6603,8 @@ int RGWRados::set_attrs(const DoutPrefixProvider *dpp, RGWObjectCtx* octx, RGWBu
66036603
struct timespec mtime_ts = real_clock::to_timespec(mtime);
66046604
op.mtime2(&mtime_ts);
66056605
auto& ioctx = ref.ioctx;
6606-
r = rgw_rados_operate(dpp, ioctx, ref.obj.oid, &op, y);
6606+
version_t epoch = 0;
6607+
r = rgw_rados_operate(dpp, ioctx, ref.obj.oid, &op, y, 0, nullptr, &epoch);
66076608
if (state) {
66086609
if (r >= 0) {
66096610
ACLOwner owner;
@@ -6634,7 +6635,6 @@ int RGWRados::set_attrs(const DoutPrefixProvider *dpp, RGWObjectCtx* octx, RGWBu
66346635
iter != state->attrset.end()) {
66356636
storage_class = rgw_bl_str(iter->second);
66366637
}
6637-
uint64_t epoch = ioctx.get_last_version();
66386638
int64_t poolid = ioctx.get_id();
66396639
r = index_op.complete(dpp, poolid, epoch, state->size, state->accounted_size,
66406640
mtime, etag, content_type, storage_class, owner,
@@ -8799,12 +8799,7 @@ int RGWRados::raw_obj_stat(const DoutPrefixProvider *dpp,
87998799
}
88008800

88018801
bufferlist outbl;
8802-
r = rgw_rados_operate(dpp, ref.ioctx, ref.obj.oid, &op, &outbl, y);
8803-
8804-
if (epoch) {
8805-
*epoch = ref.ioctx.get_last_version();
8806-
}
8807-
8802+
r = rgw_rados_operate(dpp, ref.ioctx, ref.obj.oid, &op, &outbl, y, 0, nullptr, epoch);
88088803
if (r < 0)
88098804
return r;
88108805

@@ -9655,6 +9650,12 @@ int RGWRados::cls_bucket_list_ordered(const DoutPrefixProvider *dpp,
96559650
num_entries << " total entries" << dendl;
96569651

96579652
auto& ioctx = index_pool;
9653+
9654+
// XXX: check_disk_state() relies on ioctx.get_last_version() but that
9655+
// returns 0 because CLSRGWIssueBucketList doesn't make any synchonous calls
9656+
rgw_bucket_entry_ver index_ver;
9657+
index_ver.pool = ioctx.get_id();
9658+
96589659
std::map<int, rgw_cls_list_ret> shard_list_results;
96599660
cls_rgw_obj_key start_after_key(start_after.name, start_after.instance);
96609661
r = CLSRGWIssueBucketList(ioctx, start_after_key, prefix, delimiter,
@@ -9778,12 +9779,10 @@ int RGWRados::cls_bucket_list_ordered(const DoutPrefixProvider *dpp,
97789779
/* there are uncommitted ops. We need to check the current
97799780
* state, and if the tags are old we need to do clean-up as
97809781
* well. */
9781-
librados::IoCtx sub_ctx;
9782-
sub_ctx.dup(ioctx);
97839782
ldout_bitx(bitx, dpp, 20) << "INFO: " << __func__ <<
97849783
" calling check_disk_state bucket=" << bucket_info.bucket <<
97859784
" entry=" << dirent.key << dendl_bitx;
9786-
r = check_disk_state(dpp, sub_ctx, bucket_info, dirent, dirent,
9785+
r = check_disk_state(dpp, bucket_info, index_ver, dirent, dirent,
97879786
updates[tracker.oid_name], y);
97889787
if (r < 0 && r != -ENOENT) {
97899788
ldpp_dout(dpp, 0) << __func__ <<
@@ -10005,6 +10004,9 @@ int RGWRados::cls_bucket_list_unordered(const DoutPrefixProvider *dpp,
1000510004
}
1000610005
}
1000710006

10007+
rgw_bucket_entry_ver index_ver;
10008+
index_ver.pool = ioctx.get_id();
10009+
1000810010
uint32_t count = 0u;
1000910011
std::map<std::string, bufferlist> updates;
1001010012
rgw_obj_index_key last_added_entry;
@@ -10019,7 +10021,7 @@ int RGWRados::cls_bucket_list_unordered(const DoutPrefixProvider *dpp,
1001910021
cls_rgw_bucket_list_op(op, marker, prefix, empty_delimiter,
1002010022
num_entries,
1002110023
list_versions, &result);
10022-
r = rgw_rados_operate(dpp, ioctx, oid, &op, nullptr, y);
10024+
r = rgw_rados_operate(dpp, ioctx, oid, &op, nullptr, y, 0, nullptr, &index_ver.epoch);
1002310025
if (r < 0) {
1002410026
ldpp_dout(dpp, 0) << "ERROR: " << __func__ <<
1002510027
": error in rgw_rados_operate (bucket list op), r=" << r << dendl;
@@ -10036,12 +10038,10 @@ int RGWRados::cls_bucket_list_unordered(const DoutPrefixProvider *dpp,
1003610038
force_check) {
1003710039
/* there are uncommitted ops. We need to check the current state,
1003810040
* and if the tags are old we need to do cleanup as well. */
10039-
librados::IoCtx sub_ctx;
10040-
sub_ctx.dup(ioctx);
1004110041
ldout_bitx(bitx, dpp, 20) << "INFO: " << __func__ <<
1004210042
": calling check_disk_state bucket=" << bucket_info.bucket <<
1004310043
" entry=" << dirent.key << dendl_bitx;
10044-
r = check_disk_state(dpp, sub_ctx, bucket_info, dirent, dirent, updates[oid], y);
10044+
r = check_disk_state(dpp, bucket_info, index_ver, dirent, dirent, updates[oid], y);
1004510045
if (r < 0 && r != -ENOENT) {
1004610046
ldpp_dout(dpp, 0) << "ERROR: " << __func__ <<
1004710047
": error in check_disk_state, r=" << r << dendl;
@@ -10273,8 +10273,8 @@ int RGWRados::remove_objs_from_index(const DoutPrefixProvider *dpp,
1027310273
}
1027410274

1027510275
int RGWRados::check_disk_state(const DoutPrefixProvider *dpp,
10276-
librados::IoCtx io_ctx,
1027710276
RGWBucketInfo& bucket_info,
10277+
const rgw_bucket_entry_ver& index_ver,
1027810278
rgw_bucket_dir_entry& list_state,
1027910279
rgw_bucket_dir_entry& object,
1028010280
bufferlist& suggested_updates,
@@ -10302,8 +10302,6 @@ int RGWRados::check_disk_state(const DoutPrefixProvider *dpp,
1030210302
ldpp_dout(dpp, 0) << "WARNING: generated locator (" << loc << ") is different from listed locator (" << list_state.locator << ")" << dendl;
1030310303
}
1030410304

10305-
io_ctx.locator_set_key(list_state.locator);
10306-
1030710305
RGWObjState *astate = NULL;
1030810306
RGWObjManifest *manifest = nullptr;
1030910307
RGWObjectCtx octx(this->driver);
@@ -10324,8 +10322,7 @@ int RGWRados::check_disk_state(const DoutPrefixProvider *dpp,
1032410322
}
1032510323

1032610324
// encode a suggested removal of that key
10327-
list_state.ver.epoch = io_ctx.get_last_version();
10328-
list_state.ver.pool = io_ctx.get_id();
10325+
list_state.ver = index_ver;
1032910326
ldout_bitx(bitx, dpp, 10) << "INFO: " << __func__ << ": encoding remove of " << list_state.key << " on suggested_updates" << dendl_bitx;
1033010327
cls_rgw_encode_suggestion(CEPH_RGW_REMOVE | suggest_flag, list_state, suggested_updates);
1033110328
return -ENOENT;

src/rgw/driver/rados/rgw_rados.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1642,8 +1642,8 @@ class RGWRados
16421642
* will encode that info as a suggested update.)
16431643
*/
16441644
int check_disk_state(const DoutPrefixProvider *dpp,
1645-
librados::IoCtx io_ctx,
16461645
RGWBucketInfo& bucket_info,
1646+
const rgw_bucket_entry_ver& index_ver,
16471647
rgw_bucket_dir_entry& list_state,
16481648
rgw_bucket_dir_entry& object,
16491649
bufferlist& suggested_updates,

src/rgw/driver/rados/rgw_tools.cc

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,36 +198,52 @@ int rgw_delete_system_obj(const DoutPrefixProvider *dpp,
198198

199199
int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
200200
librados::ObjectReadOperation *op, bufferlist* pbl,
201-
optional_yield y, int flags, const jspan_context* trace_info)
201+
optional_yield y, int flags, const jspan_context* trace_info,
202+
version_t* pver)
202203
{
203204
// given a yield_context, call async_operate() to yield the coroutine instead
204205
// of blocking
205206
if (y) {
206207
auto& yield = y.get_yield_context();
207208
boost::system::error_code ec;
208-
auto bl = librados::async_operate(
209+
auto [ver, bl] = librados::async_operate(
209210
yield, ioctx, oid, op, flags, trace_info, yield[ec]);
210211
if (pbl) {
211212
*pbl = std::move(bl);
212213
}
214+
if (pver) {
215+
*pver = ver;
216+
}
213217
return -ec.value();
214218
}
215219
maybe_warn_about_blocking(dpp);
216-
return ioctx.operate(oid, op, nullptr, flags);
220+
int r = ioctx.operate(oid, op, nullptr, flags);
221+
if (pver) {
222+
*pver = ioctx.get_last_version();
223+
}
224+
return r;
217225
}
218226

219227
int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
220228
librados::ObjectWriteOperation *op, optional_yield y,
221-
int flags, const jspan_context* trace_info)
229+
int flags, const jspan_context* trace_info, version_t* pver)
222230
{
223231
if (y) {
224232
auto& yield = y.get_yield_context();
225233
boost::system::error_code ec;
226-
librados::async_operate(yield, ioctx, oid, op, flags, trace_info, yield[ec]);
234+
version_t ver = librados::async_operate(yield, ioctx, oid, op, flags,
235+
trace_info, yield[ec]);
236+
if (pver) {
237+
*pver = ver;
238+
}
227239
return -ec.value();
228240
}
229241
maybe_warn_about_blocking(dpp);
230-
return ioctx.operate(oid, op, flags, trace_info);
242+
int r = ioctx.operate(oid, op, flags, trace_info);
243+
if (pver) {
244+
*pver = ioctx.get_last_version();
245+
}
246+
return r;
231247
}
232248

233249
int rgw_rados_notify(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
@@ -237,8 +253,8 @@ int rgw_rados_notify(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, cons
237253
if (y) {
238254
auto& yield = y.get_yield_context();
239255
boost::system::error_code ec;
240-
auto reply = librados::async_notify(yield, ioctx, oid,
241-
bl, timeout_ms, yield[ec]);
256+
auto [ver, reply] = librados::async_notify(yield, ioctx, oid,
257+
bl, timeout_ms, yield[ec]);
242258
if (pbl) {
243259
*pbl = std::move(reply);
244260
}

src/rgw/driver/rados/rgw_tools.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,12 @@ void rgw_filter_attrset(std::map<std::string, bufferlist>& unfiltered_attrset, c
9393
/// perform the rados operation, using the yield context when given
9494
int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
9595
librados::ObjectReadOperation *op, bufferlist* pbl,
96-
optional_yield y, int flags = 0, const jspan_context* trace_info = nullptr);
96+
optional_yield y, int flags = 0, const jspan_context* trace_info = nullptr,
97+
version_t* pver = nullptr);
9798
int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
9899
librados::ObjectWriteOperation *op, optional_yield y,
99-
int flags = 0, const jspan_context* trace_info = nullptr);
100+
int flags = 0, const jspan_context* trace_info = nullptr,
101+
version_t* pver = nullptr);
100102
int rgw_rados_notify(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
101103
bufferlist& bl, uint64_t timeout_ms, bufferlist* pbl,
102104
optional_yield y);

src/rgw/rgw_aio.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ struct Handler {
7676
librados::IoCtx ctx;
7777
AioResult& r;
7878
// write callback
79-
void operator()(boost::system::error_code ec) const {
79+
void operator()(boost::system::error_code ec, version_t) const {
8080
r.result = -ec.value();
8181
throttle->put(r);
8282
}
8383
// read callback
84-
void operator()(boost::system::error_code ec, bufferlist bl) const {
84+
void operator()(boost::system::error_code ec, version_t, bufferlist bl) const {
8585
r.result = -ec.value();
8686
r.data = std::move(bl);
8787
throttle->put(r);

src/rgw/services/svc_sys_obj_core.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,21 +169,21 @@ int RGWSI_SysObj_Core::read(const DoutPrefixProvider *dpp,
169169
}
170170
}
171171

172-
rgw_rados_ref rados_obj;
173-
int r = get_rados_obj(dpp, zone_svc, obj, &rados_obj);
172+
rgw_rados_ref ref;
173+
int r = get_rados_obj(dpp, zone_svc, obj, &ref);
174174
if (r < 0) {
175175
ldpp_dout(dpp, 20) << "get_rados_obj() on obj=" << obj << " returned " << r << dendl;
176176
return r;
177177
}
178-
r = rados_obj.operate(dpp, &op, nullptr, y);
178+
179+
version_t op_ver = 0;
180+
r = rgw_rados_operate(dpp, ref.ioctx, obj.oid, &op, nullptr, y, 0, nullptr, &op_ver);
179181
if (r < 0) {
180182
ldpp_dout(dpp, 20) << "rados_obj.operate() r=" << r << " bl.length=" << bl->length() << dendl;
181183
return r;
182184
}
183185
ldpp_dout(dpp, 20) << "rados_obj.operate() r=" << r << " bl.length=" << bl->length() << dendl;
184186

185-
uint64_t op_ver = rados_obj.ioctx.get_last_version();
186-
187187
if (read_state.last_ver > 0 &&
188188
read_state.last_ver != op_ver) {
189189
ldpp_dout(dpp, 5) << "raced with an object write, abort" << dendl;

0 commit comments

Comments
 (0)