Skip to content

Commit 42ecd4c

Browse files
authored
Merge pull request ceph#58213 from benhanokh/ref_count
rgw/rgw_rados: fix server side-copy orphans tail-objects Reviewed-by: Casey Bodley <[email protected]>
2 parents 663f52f + 01a9cfb commit 42ecd4c

File tree

5 files changed

+136
-17
lines changed

5 files changed

+136
-17
lines changed

qa/workunits/rgw/test_rgw_orphan_list.sh

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ set -e
66
# if defined, debug messages will be displayed and prepended with the string
77
# debug="DEBUG"
88

9-
huge_size=5100 # in megabytes
9+
#huge_size=5100 # in megabytes
10+
huge_size=51 # in megabytes
1011
big_size=7 # in megabytes
1112

1213
huge_obj=/tmp/huge_obj.temp.$$
@@ -376,6 +377,95 @@ done
376377

377378
mys3cmd rb --recursive s3://$o_bkt
378379

380+
############################################################
381+
# copy multipart objects and delete destination
382+
383+
o_bkt="orig-mp-bkt-5"
384+
d_bkt="copy-mp-bkt-5"
385+
386+
mys3cmd mb s3://$o_bkt
387+
388+
for f in $(seq 2) ;do
389+
dest_obj="orig-multipart-obj-$f"
390+
mys3cmd put -q $huge_obj s3://${o_bkt}/$dest_obj
391+
done
392+
393+
mys3cmd mb s3://$d_bkt
394+
395+
mys3cmd cp s3://${o_bkt}/orig-multipart-obj-1 \
396+
s3://${d_bkt}/copied-multipart-obj-1
397+
398+
for f in $(seq 5 5) ;do
399+
dest_obj="orig-multipart-obj-$f"
400+
mys3cmd put -q $huge_obj s3://${d_bkt}/$dest_obj
401+
done
402+
403+
mys3cmd rb --recursive s3://$d_bkt
404+
405+
#####################################################################
406+
# FORCE GARBAGE COLLECTION
407+
sleep 6 # since for testing age at which gc can happen is 5 secs
408+
radosgw-admin gc process --include-all
409+
#####################################################################
410+
411+
############################################################
412+
# copy multipart objects and delete original then destination
413+
414+
o_bkt="orig-mp-bkt-6"
415+
d_bkt="copy-mp-bkt-6"
416+
417+
mys3cmd mb s3://$o_bkt
418+
419+
for f in $(seq 2) ;do
420+
dest_obj="orig-multipart-obj-$f"
421+
mys3cmd put -q $huge_obj s3://${o_bkt}/$dest_obj
422+
done
423+
424+
mys3cmd mb s3://$d_bkt
425+
426+
mys3cmd cp s3://${o_bkt}/orig-multipart-obj-1 \
427+
s3://${d_bkt}/copied-multipart-obj-1
428+
429+
for f in $(seq 5 5) ;do
430+
dest_obj="orig-multipart-obj-$f"
431+
mys3cmd put -q $huge_obj s3://${d_bkt}/$dest_obj
432+
done
433+
434+
mys3cmd rb --recursive s3://$o_bkt
435+
mys3cmd rb --recursive s3://$d_bkt
436+
437+
############################################################
438+
# copy multipart objects and delete destination then original
439+
440+
o_bkt="orig-mp-bkt-7"
441+
d_bkt="copy-mp-bkt-7"
442+
443+
mys3cmd mb s3://$o_bkt
444+
445+
for f in $(seq 2) ;do
446+
dest_obj="orig-multipart-obj-$f"
447+
mys3cmd put -q $huge_obj s3://${o_bkt}/$dest_obj
448+
done
449+
450+
mys3cmd mb s3://$d_bkt
451+
452+
mys3cmd cp s3://${o_bkt}/orig-multipart-obj-1 \
453+
s3://${d_bkt}/copied-multipart-obj-1
454+
455+
for f in $(seq 5 5) ;do
456+
dest_obj="orig-multipart-obj-$f"
457+
mys3cmd put -q $huge_obj s3://${d_bkt}/$dest_obj
458+
done
459+
460+
mys3cmd rb --recursive s3://$d_bkt
461+
mys3cmd rb --recursive s3://$o_bkt
462+
463+
#####################################################################
464+
# FORCE GARBAGE COLLECTION
465+
sleep 6 # since for testing age at which gc can happen is 5 secs
466+
radosgw-admin gc process --include-all
467+
#####################################################################
468+
379469
########################################################################
380470
# SWIFT TESTS
381471

src/rgw/driver/rados/rgw_rados.cc

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2915,6 +2915,7 @@ int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx,
29152915
jspan_context no_trace{false, false};
29162916

29172917
r = copy_obj(obj_ctx,
2918+
obj_ctx, /* src and dest share an obj_ctx */
29182919
owner,
29192920
remote_user,
29202921
NULL, /* req_info *info */
@@ -3014,6 +3015,7 @@ int RGWRados::swift_versioning_restore(RGWObjectCtx& obj_ctx,
30143015
jspan_context no_trace{false, false};
30153016

30163017
int ret = copy_obj(obj_ctx,
3018+
obj_ctx, /* src and dest share an obj_ctx */
30173019
owner,
30183020
remote_user,
30193021
nullptr, /* req_info *info */
@@ -4154,7 +4156,7 @@ int RGWFetchObjFilter_Default::filter(CephContext *cct,
41544156
return 0;
41554157
}
41564158

4157-
int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
4159+
int RGWRados::fetch_remote_obj(RGWObjectCtx& dest_obj_ctx,
41584160
const rgw_user& user_id,
41594161
req_info *info,
41604162
const rgw_zone_id& source_zone,
@@ -4206,7 +4208,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
42064208
using namespace rgw::putobj;
42074209
jspan_context no_trace{false, false};
42084210
AtomicObjectProcessor processor(&aio, this, dest_bucket_info, nullptr,
4209-
owner, obj_ctx, dest_obj, olh_epoch,
4211+
owner, dest_obj_ctx, dest_obj, olh_epoch,
42104212
tag, rctx.dpp, rctx.y, no_trace);
42114213
RGWRESTConn *conn;
42124214
auto& zone_conn_map = svc.zone->get_zone_conn_map();
@@ -4290,7 +4292,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
42904292

42914293
if (copy_if_newer) {
42924294
/* need to get mtime for destination */
4293-
ret = get_obj_state(rctx.dpp, &obj_ctx, dest_bucket_info, stat_dest_obj, &dest_state, &manifest, stat_follow_olh, rctx.y);
4295+
ret = get_obj_state(rctx.dpp, &dest_obj_ctx, dest_bucket_info, stat_dest_obj, &dest_state, &manifest, stat_follow_olh, rctx.y);
42944296
if (ret < 0)
42954297
goto set_err_state;
42964298

@@ -4499,8 +4501,8 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
44994501

45004502
if (copy_if_newer && canceled) {
45014503
ldpp_dout(rctx.dpp, 20) << "raced with another write of obj: " << dest_obj << dendl;
4502-
obj_ctx.invalidate(dest_obj); /* object was overwritten */
4503-
ret = get_obj_state(rctx.dpp, &obj_ctx, dest_bucket_info, stat_dest_obj, &dest_state, &manifest, stat_follow_olh, rctx.y);
4504+
dest_obj_ctx.invalidate(dest_obj); /* object was overwritten */
4505+
ret = get_obj_state(rctx.dpp, &dest_obj_ctx, dest_bucket_info, stat_dest_obj, &dest_state, &manifest, stat_follow_olh, rctx.y);
45044506
if (ret < 0) {
45054507
ldpp_dout(rctx.dpp, 0) << "ERROR: " << __func__ << ": get_err_state() returned ret=" << ret << dendl;
45064508
goto set_err_state;
@@ -4534,7 +4536,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
45344536
// for OP_LINK_OLH to call set_olh() with a real olh_epoch
45354537
if (olh_epoch && *olh_epoch > 0) {
45364538
constexpr bool log_data_change = true;
4537-
ret = set_olh(rctx.dpp, obj_ctx, dest_bucket_info, dest_obj, false, nullptr,
4539+
ret = set_olh(rctx.dpp, dest_obj_ctx, dest_bucket_info, dest_obj, false, nullptr,
45384540
*olh_epoch, real_time(), false, rctx.y, zones_trace, log_data_change);
45394541
} else {
45404542
// we already have the latest copy
@@ -4609,7 +4611,8 @@ int RGWRados::copy_obj_to_remote_dest(const DoutPrefixProvider *dpp,
46094611
* err: stores any errors resulting from the get of the original object
46104612
* Returns: 0 on success, -ERR# otherwise.
46114613
*/
4612-
int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
4614+
int RGWRados::copy_obj(RGWObjectCtx& src_obj_ctx,
4615+
RGWObjectCtx& dest_obj_ctx,
46134616
const ACLOwner& owner,
46144617
const rgw_user& remote_user,
46154618
req_info *info,
@@ -4670,7 +4673,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
46704673
if (remote_src || !source_zone.empty()) {
46714674
rgw_zone_set_entry source_trace_entry{source_zone.id, std::nullopt};
46724675
const req_context rctx{dpp, y, nullptr};
4673-
return fetch_remote_obj(obj_ctx, remote_user, info, source_zone,
4676+
return fetch_remote_obj(dest_obj_ctx, remote_user, info, source_zone,
46744677
dest_obj, src_obj, dest_bucket_info, &src_bucket_info,
46754678
dest_placement, src_mtime, mtime, mod_ptr,
46764679
unmod_ptr, high_precision_time,
@@ -4680,7 +4683,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
46804683
}
46814684

46824685
map<string, bufferlist> src_attrs;
4683-
RGWRados::Object src_op_target(this, src_bucket_info, obj_ctx, src_obj);
4686+
RGWRados::Object src_op_target(this, src_bucket_info, src_obj_ctx, src_obj);
46844687
RGWRados::Object::Read read_op(&src_op_target);
46854688

46864689
read_op.conds.mod_ptr = mod_ptr;
@@ -4741,7 +4744,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
47414744
RGWObjManifest *amanifest = nullptr;
47424745

47434746
constexpr bool follow_olh = true;
4744-
ret = get_obj_state(dpp, &obj_ctx, src_bucket_info, src_obj,
4747+
ret = get_obj_state(dpp, &src_obj_ctx, src_bucket_info, src_obj,
47454748
&astate, &amanifest, follow_olh, y);
47464749
if (ret < 0) {
47474750
return ret;
@@ -4818,7 +4821,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
48184821

48194822
if (copy_data) { /* refcounting tail wouldn't work here, just copy the data */
48204823
attrs.erase(RGW_ATTR_TAIL_TAG);
4821-
return copy_obj_data(obj_ctx, owner, dest_bucket_info, dest_placement, read_op, obj_size - 1, dest_obj,
4824+
return copy_obj_data(dest_obj_ctx, owner, dest_bucket_info, dest_placement, read_op, obj_size - 1, dest_obj,
48224825
mtime, real_time(), attrs, olh_epoch, delete_at, petag, dpp, y);
48234826
}
48244827

@@ -4835,7 +4838,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
48354838
RGWObjManifest *pmanifest;
48364839
ldpp_dout(dpp, 20) << "dest_obj=" << dest_obj << " src_obj=" << src_obj << " copy_itself=" << (int)copy_itself << dendl;
48374840

4838-
RGWRados::Object dest_op_target(this, dest_bucket_info, obj_ctx, dest_obj);
4841+
RGWRados::Object dest_op_target(this, dest_bucket_info, dest_obj_ctx, dest_obj);
48394842
RGWRados::Object::Write write_op(&dest_op_target);
48404843

48414844
string tag;

src/rgw/driver/rados/rgw_rados.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ class RGWRados
11331133
std::string *ptag,
11341134
std::string *petag, optional_yield y);
11351135

1136-
int fetch_remote_obj(RGWObjectCtx& obj_ctx,
1136+
int fetch_remote_obj(RGWObjectCtx& dest_obj_ctx,
11371137
const rgw_user& user_id,
11381138
req_info *info,
11391139
const rgw_zone_id& source_zone,
@@ -1180,7 +1180,8 @@ class RGWRados
11801180
* are overwritten by values contained in attrs parameter.
11811181
* Returns: 0 on success, -ERR# otherwise.
11821182
*/
1183-
int copy_obj(RGWObjectCtx& obj_ctx,
1183+
int copy_obj(RGWObjectCtx& src_obj_ctx,
1184+
RGWObjectCtx& dest_obj_ctx,
11841185
const ACLOwner& owner, // owner of destination object
11851186
const rgw_user& remote_user, // uid for fetch_remote_obj() auth
11861187
req_info *info,

src/rgw/driver/rados/rgw_sal_rados.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2903,6 +2903,7 @@ int RadosObject::copy_object(const ACLOwner& owner,
29032903
optional_yield y)
29042904
{
29052905
return store->getRados()->copy_obj(*rados_ctx,
2906+
*static_cast<RadosObject*>(dest_object)->rados_ctx,
29062907
owner,
29072908
remote_user,
29082909
info,

src/tools/rados/rados.cc

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
#include "RadosImport.h"
6060

6161
#include "osd/ECUtil.h"
62+
#include "objclass/objclass.h"
63+
#include "cls/refcount/cls_refcount_ops.h"
6264

6365
using namespace std::chrono_literals;
6466
using namespace librados;
@@ -2750,8 +2752,30 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
27502752
}
27512753
else
27522754
ret = 0;
2753-
string s(bl.c_str(), bl.length());
2754-
cout << s;
2755+
2756+
if (attr_name == "refcount") {
2757+
obj_refcount oref;
2758+
auto p = bl.cbegin();
2759+
decode(oref, p);
2760+
for (auto itr = oref.refs.begin(); itr != oref.refs.end(); itr++) {
2761+
if (!itr->first.empty()) {
2762+
cout << itr->first << "::" << itr->second << std::endl;
2763+
}
2764+
else {
2765+
cout << "wildcard reference::" << itr->second << std::endl;
2766+
}
2767+
}
2768+
if (!oref.retired_refs.empty()) {
2769+
cout << "--------------------------------------" << std::endl;
2770+
for (const auto & ref : oref.retired_refs) {
2771+
cout << "retired_refs::" << ref << std::endl;
2772+
}
2773+
}
2774+
}
2775+
else {
2776+
string s(bl.c_str(), bl.length());
2777+
cout << s << std::endl;
2778+
}
27552779
} else if (strcmp(nargs[0], "rmxattr") == 0) {
27562780
if (!pool_name || nargs.size() < (obj_name ? 2 : 3)) {
27572781
usage(cerr);

0 commit comments

Comments
 (0)