Skip to content

Commit 333e4a9

Browse files
rgw: keep the tails when copying object to itself
Signed-off-by: Jane Zhu <[email protected]>
1 parent f75bfa4 commit 333e4a9

File tree

3 files changed

+46
-14
lines changed

3 files changed

+46
-14
lines changed

qa/workunits/rgw/test_rgw_orphan_list.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,37 @@ done
460460
mys3cmd rb --recursive s3://$d_bkt
461461
mys3cmd rb --recursive s3://$o_bkt
462462

463+
############################################################
464+
# copy a multipart object to itself
465+
# run gc process after the copy, then try to get the object
466+
467+
o_bkt="orig-mp-bkt-8"
468+
469+
mys3cmd mb s3://$o_bkt
470+
471+
mp_obj="multipart-obj-1"
472+
mys3cmd put -q $huge_obj s3://${o_bkt}/$mp_obj
473+
474+
mys3cmd cp --mime-type="text/plain" s3://${o_bkt}/$mp_obj s3://${o_bkt}/$mp_obj
475+
476+
#####################################################################
477+
# FORCE GARBAGE COLLECTION
478+
sleep 6 # since for testing age at which gc can happen is 5 secs
479+
radosgw-admin gc process --include-all
480+
#####################################################################
481+
482+
mp_obj_retrieved="multipart-obj-1-retrieved"
483+
mys3cmd get s3://${o_bkt}/$mp_obj $mp_obj_retrieved --force
484+
485+
if [ -f $mp_obj_retrieved ]; then
486+
rm -f $mp_obj_retrieved
487+
else
488+
echo "ERROR: failed to get the object after copying to itself"
489+
exit 1
490+
fi
491+
492+
mys3cmd rb --recursive s3://$o_bkt
493+
463494
#####################################################################
464495
# FORCE GARBAGE COLLECTION
465496
sleep 6 # since for testing age at which gc can happen is 5 secs

src/rgw/driver/rados/rgw_rados.cc

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3127,8 +3127,8 @@ int RGWRados::swift_versioning_restore(RGWObjectCtx& obj_ctx,
31273127

31283128
int RGWRados::Object::Write::_do_write_meta(uint64_t size, uint64_t accounted_size,
31293129
map<string, bufferlist>& attrs,
3130-
bool assume_noent, bool modify_tail,
3131-
void *_index_op, const req_context& rctx,
3130+
bool assume_noent, void *_index_op,
3131+
const req_context& rctx,
31323132
jspan_context& trace, bool log_op)
31333133
{
31343134
RGWRados::Bucket::UpdateIndex *index_op = static_cast<RGWRados::Bucket::UpdateIndex *>(_index_op);
@@ -3172,7 +3172,7 @@ int RGWRados::Object::Write::_do_write_meta(uint64_t size, uint64_t accounted_si
31723172
if (!ptag && !index_op->get_optag()->empty()) {
31733173
ptag = index_op->get_optag();
31743174
}
3175-
r = target->prepare_atomic_modification(rctx.dpp, op, reset_obj, ptag, meta.if_match, meta.if_nomatch, false, modify_tail, rctx.y);
3175+
r = target->prepare_atomic_modification(rctx.dpp, op, reset_obj, ptag, meta.if_match, meta.if_nomatch, false, meta.modify_tail, rctx.y);
31763176
if (r < 0)
31773177
return r;
31783178

@@ -3339,7 +3339,7 @@ int RGWRados::Object::Write::_do_write_meta(uint64_t size, uint64_t accounted_si
33393339

33403340
poolid = ioctx.get_id();
33413341

3342-
r = target->complete_atomic_modification(rctx.dpp, rctx.y);
3342+
r = target->complete_atomic_modification(rctx.dpp, meta.keep_tail, rctx.y);
33433343
if (r < 0) {
33443344
ldpp_dout(rctx.dpp, 0) << "ERROR: complete_atomic_modification returned r=" << r << dendl;
33453345
}
@@ -3457,13 +3457,13 @@ int RGWRados::Object::Write::write_meta(uint64_t size, uint64_t accounted_size,
34573457
bool assume_noent = (meta.if_match == NULL && meta.if_nomatch == NULL);
34583458
int r;
34593459
if (assume_noent) {
3460-
r = _do_write_meta(size, accounted_size, attrs, assume_noent, meta.modify_tail, (void *)&index_op, rctx, trace, log_op);
3460+
r = _do_write_meta(size, accounted_size, attrs, assume_noent, (void *)&index_op, rctx, trace, log_op);
34613461
if (r == -EEXIST) {
34623462
assume_noent = false;
34633463
}
34643464
}
34653465
if (!assume_noent) {
3466-
r = _do_write_meta(size, accounted_size, attrs, assume_noent, meta.modify_tail, (void *)&index_op, rctx, trace, log_op);
3466+
r = _do_write_meta(size, accounted_size, attrs, assume_noent, (void *)&index_op, rctx, trace, log_op);
34673467
}
34683468
return r;
34693469
}
@@ -5037,6 +5037,7 @@ int RGWRados::copy_obj(RGWObjectCtx& src_obj_ctx,
50375037
write_op.meta.olh_epoch = olh_epoch;
50385038
write_op.meta.delete_at = delete_at;
50395039
write_op.meta.modify_tail = !copy_itself;
5040+
write_op.meta.keep_tail = copy_itself;
50405041

50415042
ret = write_op.write_meta(obj_size, astate->accounted_size, attrs, rctx, trace);
50425043
if (ret < 0) {
@@ -5659,9 +5660,9 @@ int RGWRados::bucket_suspended(const DoutPrefixProvider *dpp, rgw_bucket& bucket
56595660
return 0;
56605661
}
56615662

5662-
int RGWRados::Object::complete_atomic_modification(const DoutPrefixProvider *dpp, optional_yield y)
5663+
int RGWRados::Object::complete_atomic_modification(const DoutPrefixProvider *dpp, bool keep_tail, optional_yield y)
56635664
{
5664-
if ((!manifest)|| state->keep_tail)
5665+
if ((!manifest) || state->keep_tail || keep_tail)
56655666
return 0;
56665667

56675668
cls_rgw_obj_chain chain;
@@ -6238,7 +6239,7 @@ int RGWRados::Object::Delete::delete_obj(optional_yield y, const DoutPrefixProvi
62386239
}
62396240
r = index_op.complete_del(dpp, poolid, epoch, state->mtime, params.remove_objs, y, log_op);
62406241

6241-
int ret = target->complete_atomic_modification(dpp, y);
6242+
int ret = target->complete_atomic_modification(dpp, false, y);
62426243
if (ret < 0) {
62436244
ldpp_dout(dpp, 0) << "ERROR: complete_atomic_modification returned ret=" << ret << dendl;
62446245
}

src/rgw/driver/rados/rgw_rados.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ class RGWRados
695695

696696
int prepare_atomic_modification(const DoutPrefixProvider *dpp, librados::ObjectWriteOperation& op, bool reset_obj, const std::string *ptag,
697697
const char *ifmatch, const char *ifnomatch, bool removal_op, bool modify_tail, optional_yield y);
698-
int complete_atomic_modification(const DoutPrefixProvider *dpp, optional_yield y);
698+
int complete_atomic_modification(const DoutPrefixProvider *dpp, bool keep_tail, optional_yield y);
699699

700700
public:
701701
Object(RGWRados *_store, const RGWBucketInfo& _bucket_info, RGWObjectCtx& _ctx, const rgw_obj& _obj) : store(_store), bucket_info(_bucket_info),
@@ -813,22 +813,22 @@ class RGWRados
813813
const std::string *user_data;
814814
rgw_zone_set *zones_trace;
815815
bool modify_tail;
816+
bool keep_tail;
816817
bool completeMultipart;
817818
bool appendable;
818819

819820
MetaParams() : mtime(NULL), rmattrs(NULL), data(NULL), manifest(NULL), ptag(NULL),
820821
remove_objs(NULL), category(RGWObjCategory::Main), flags(0),
821822
if_match(NULL), if_nomatch(NULL), canceled(false), user_data(nullptr), zones_trace(nullptr),
822-
modify_tail(false), completeMultipart(false), appendable(false) {}
823+
modify_tail(false), keep_tail(false), completeMultipart(false), appendable(false) {}
823824
} meta;
824825

825826
explicit Write(RGWRados::Object *_target) : target(_target) {}
826827

827828
int _do_write_meta(uint64_t size, uint64_t accounted_size,
828829
std::map<std::string, bufferlist>& attrs,
829-
bool modify_tail, bool assume_noent,
830-
void *index_op, const req_context& rctx,
831-
jspan_context& trace,
830+
bool assume_noent, void *index_op,
831+
const req_context& rctx, jspan_context& trace,
832832
bool log_op = true);
833833
int write_meta(uint64_t size, uint64_t accounted_size,
834834
std::map<std::string, bufferlist>& attrs,

0 commit comments

Comments
 (0)