Skip to content

Commit 2c46870

Browse files
authored
Merge pull request ceph#59611 from cbodley/wip-cls-rgw-busy-resharding
cls/rgw: duplicate reshard checks in all cls_rgw write operations Reviewed-by: J. Eric Ivancich <[email protected]>
2 parents 54b91e9 + d011c52 commit 2c46870

File tree

14 files changed

+374
-210
lines changed

14 files changed

+374
-210
lines changed

src/cls/rgw/cls_rgw.cc

Lines changed: 183 additions & 93 deletions
Large diffs are not rendered by default.

src/cls/rgw/cls_rgw_client.cc

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ bool BucketIndexAioManager::wait_for_completions(int valid_ret_code,
186186
return true;
187187
}
188188

189-
// note: currently only called by testing code
190189
void cls_rgw_bucket_init_index(ObjectWriteOperation& o)
191190
{
192191
bufferlist in;
@@ -200,18 +199,24 @@ static bool issue_bucket_index_init_op(librados::IoCtx& io_ctx,
200199
bufferlist in;
201200
librados::ObjectWriteOperation op;
202201
op.create(true);
203-
op.exec(RGW_CLASS, RGW_BUCKET_INIT_INDEX, in);
202+
cls_rgw_bucket_init_index(op);
204203
return manager->aio_operate(io_ctx, shard_id, oid, &op);
205204
}
206205

206+
void cls_rgw_bucket_init_index2(ObjectWriteOperation& o)
207+
{
208+
bufferlist in;
209+
o.exec(RGW_CLASS, RGW_BUCKET_INIT_INDEX2, in);
210+
}
211+
207212
static bool issue_bucket_index_init_op2(librados::IoCtx& io_ctx,
208213
const int shard_id,
209214
const string& oid,
210215
BucketIndexAioManager *manager) {
211216
bufferlist in;
212217
librados::ObjectWriteOperation op;
213218
op.create(true);
214-
op.exec(RGW_CLASS, RGW_BUCKET_INIT_INDEX2, in);
219+
cls_rgw_bucket_init_index2(op);
215220
return manager->aio_operate(io_ctx, shard_id, oid, &op);
216221
}
217222

@@ -470,32 +475,6 @@ int cls_rgw_bi_get(librados::IoCtx& io_ctx, const string oid,
470475
return 0;
471476
}
472477

473-
int cls_rgw_bi_get_vals(librados::IoCtx& io_ctx, const std::string oid,
474-
std::set<std::string>& log_entries_wanted,
475-
std::list<rgw_cls_bi_entry> *entries)
476-
{
477-
bufferlist in, out;
478-
struct rgw_cls_bi_get_vals_op call;
479-
call.log_entries_wanted = std::move(log_entries_wanted);
480-
encode(call, in);
481-
int r = io_ctx.exec(oid, RGW_CLASS, RGW_BI_GET_VALS, in, out);
482-
if (r < 0)
483-
return r;
484-
485-
struct rgw_cls_bi_list_ret op_ret;
486-
auto iter = out.cbegin();
487-
try {
488-
decode(op_ret, iter);
489-
} catch (ceph::buffer::error& err) {
490-
return -EIO;
491-
}
492-
493-
if (entries)
494-
entries->swap(op_ret.entries);
495-
496-
return 0;
497-
}
498-
499478
int cls_rgw_bi_put(librados::IoCtx& io_ctx, const string oid, const rgw_cls_bi_entry& entry)
500479
{
501480
bufferlist in, out;
@@ -518,6 +497,21 @@ void cls_rgw_bi_put(ObjectWriteOperation& op, const string oid, const rgw_cls_bi
518497
op.exec(RGW_CLASS, RGW_BI_PUT, in);
519498
}
520499

500+
void cls_rgw_bi_put_entries(librados::ObjectWriteOperation& op,
501+
std::vector<rgw_cls_bi_entry> entries,
502+
bool check_existing)
503+
{
504+
const auto call = rgw_cls_bi_put_entries_op{
505+
.entries = std::move(entries),
506+
.check_existing = check_existing
507+
};
508+
509+
bufferlist in;
510+
encode(call, in);
511+
512+
op.exec(RGW_CLASS, RGW_BI_PUT_ENTRIES, in);
513+
}
514+
521515
/* nb: any entries passed in are replaced with the results of the cls
522516
* call, so caller does not need to clear entries between calls
523517
*/

src/cls/rgw/cls_rgw_client.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ class BucketIndexShardsManager {
264264

265265
/* bucket index */
266266
void cls_rgw_bucket_init_index(librados::ObjectWriteOperation& o);
267+
void cls_rgw_bucket_init_index2(librados::ObjectWriteOperation& o);
267268

268269
class CLSRGWConcurrentIO {
269270
protected:
@@ -383,11 +384,14 @@ void cls_rgw_obj_check_mtime(librados::ObjectOperation& o, const ceph::real_time
383384
int cls_rgw_bi_get(librados::IoCtx& io_ctx, const std::string oid,
384385
BIIndexType index_type, const cls_rgw_obj_key& key,
385386
rgw_cls_bi_entry *entry);
386-
int cls_rgw_bi_get_vals(librados::IoCtx& io_ctx, const std::string oid,
387-
std::set<std::string>& log_entries_wanted,
388-
std::list<rgw_cls_bi_entry> *entries);
389387
int cls_rgw_bi_put(librados::IoCtx& io_ctx, const std::string oid, const rgw_cls_bi_entry& entry);
390388
void cls_rgw_bi_put(librados::ObjectWriteOperation& op, const std::string oid, const rgw_cls_bi_entry& entry);
389+
// Write the given array of index entries and update bucket stats accordingly.
390+
// If existing entries may be overwritten, pass check_existing=true to decrement
391+
// their stats first.
392+
void cls_rgw_bi_put_entries(librados::ObjectWriteOperation& op,
393+
std::vector<rgw_cls_bi_entry> entries,
394+
bool check_existing);
391395
int cls_rgw_bi_list(librados::IoCtx& io_ctx, const std::string& oid,
392396
const std::string& name, const std::string& marker, uint32_t max,
393397
std::list<rgw_cls_bi_entry> *entries, bool *is_truncated, bool reshardlog = false);
@@ -671,8 +675,16 @@ int cls_rgw_reshard_list(librados::IoCtx& io_ctx, const std::string& oid, std::s
671675
int cls_rgw_reshard_get(librados::IoCtx& io_ctx, const std::string& oid, cls_rgw_reshard_entry& entry);
672676
#endif
673677

674-
/* resharding attribute on bucket index shard headers */
678+
// If writes to the bucket index should be blocked during resharding, fail with
679+
// the given error code. RGWRados::guard_reshard() calls this in a loop to retry
680+
// the write until the reshard completes.
681+
//
682+
// As of the T release, all index write ops in cls_rgw perform this check
683+
// themselves. RGW can stop issuing this call in the T+2 (V) release once it
684+
// knows that OSDs are running T at least. The call can be safely removed from
685+
// cls_rgw in the T+4 (X) release.
675686
void cls_rgw_guard_bucket_resharding(librados::ObjectOperation& op, int ret_err);
687+
676688
// these overloads which call io_ctx.operate() should not be called in the rgw.
677689
// rgw_rados_operate() should be called after the overloads w/o calls to io_ctx.operate()
678690
#ifndef CLS_CLIENT_HIDE_IOCTX

src/cls/rgw/cls_rgw_const.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ constexpr int RGWBIAdvanceAndRetryError = -EFBIG;
3333
#define RGW_OBJ_CHECK_MTIME "obj_check_mtime"
3434

3535
#define RGW_BI_GET "bi_get"
36-
#define RGW_BI_GET_VALS "bi_get_vals"
3736
#define RGW_BI_PUT "bi_put"
37+
#define RGW_BI_PUT_ENTRIES "bi_put_entries"
3838
#define RGW_BI_LIST "bi_list"
3939

4040
#define RGW_RESHARD_LOG_TRIM "reshard_log_trim"

src/cls/rgw/cls_rgw_ops.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,3 +580,9 @@ void cls_rgw_get_bucket_resharding_op::generate_test_instances(
580580
void cls_rgw_get_bucket_resharding_op::dump(Formatter *f) const
581581
{
582582
}
583+
584+
void rgw_cls_bi_put_entries_op::dump(Formatter *f) const
585+
{
586+
encode_json("entries", entries, f);
587+
encode_json("check_existing", check_existing, f);
588+
}

src/cls/rgw/cls_rgw_ops.h

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -731,23 +731,6 @@ struct rgw_cls_bi_get_ret {
731731
};
732732
WRITE_CLASS_ENCODER(rgw_cls_bi_get_ret)
733733

734-
struct rgw_cls_bi_get_vals_op {
735-
std::set<std::string> log_entries_wanted;
736-
737-
void encode(ceph::buffer::list& bl) const {
738-
ENCODE_START(1, 1, bl);
739-
encode(log_entries_wanted, bl);
740-
ENCODE_FINISH(bl);
741-
}
742-
743-
void decode(ceph::buffer::list::const_iterator& bl) {
744-
DECODE_START(1, bl);
745-
decode(log_entries_wanted, bl);
746-
DECODE_FINISH(bl);
747-
}
748-
};
749-
WRITE_CLASS_ENCODER(rgw_cls_bi_get_vals_op)
750-
751734
struct rgw_cls_bi_put_op {
752735
rgw_cls_bi_entry entry;
753736

@@ -777,6 +760,35 @@ struct rgw_cls_bi_put_op {
777760
};
778761
WRITE_CLASS_ENCODER(rgw_cls_bi_put_op)
779762

763+
struct rgw_cls_bi_put_entries_op {
764+
std::vector<rgw_cls_bi_entry> entries;
765+
bool check_existing = false;
766+
767+
void encode(ceph::buffer::list& bl) const {
768+
ENCODE_START(1, 1, bl);
769+
encode(entries, bl);
770+
encode(check_existing, bl);
771+
ENCODE_FINISH(bl);
772+
}
773+
774+
void decode(ceph::buffer::list::const_iterator& bl) {
775+
DECODE_START(1, bl);
776+
decode(entries, bl);
777+
decode(check_existing, bl);
778+
DECODE_FINISH(bl);
779+
}
780+
781+
void dump(ceph::Formatter *f) const;
782+
783+
static void generate_test_instances(std::list<rgw_cls_bi_put_entries_op*>& o) {
784+
o.push_back(new rgw_cls_bi_put_entries_op);
785+
o.push_back(new rgw_cls_bi_put_entries_op);
786+
o.back()->entries.push_back({.idx = "entry"});
787+
o.back()->check_existing = true;
788+
}
789+
};
790+
WRITE_CLASS_ENCODER(rgw_cls_bi_put_entries_op)
791+
780792
struct rgw_cls_bi_list_op {
781793
uint32_t max;
782794
std::string name_filter; // limit result to one object and its instances

src/cls/rgw/cls_rgw_types.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ void rgw_cls_bi_entry::dump(Formatter *f) const
406406

407407
bool rgw_cls_bi_entry::get_info(cls_rgw_obj_key *key,
408408
RGWObjCategory *category,
409-
rgw_bucket_category_stats *accounted_stats)
409+
rgw_bucket_category_stats *accounted_stats) const
410410
{
411411
using ceph::decode;
412412
auto iter = data.cbegin();

src/cls/rgw/cls_rgw_types.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#define CEPH_RGW_DIR_SUGGEST_LOG_OP 0x80
1919
#define CEPH_RGW_DIR_SUGGEST_OP_MASK 0x7f
2020

21+
#define CLS_RGW_ERR_BUSY_RESHARDING 2300 // also in rgw_common.h, don't change!
22+
2123
constexpr uint64_t CEPH_RGW_DEFAULT_TAG_TIMEOUT = 120; // in seconds
2224

2325
class JSONObj;
@@ -197,20 +199,17 @@ inline std::ostream& operator<<(std::ostream& out, RGWObjCategory c) {
197199
}
198200

199201
struct rgw_bucket_dir_entry_meta {
200-
RGWObjCategory category;
201-
uint64_t size;
202+
RGWObjCategory category = RGWObjCategory::None;
203+
uint64_t size = 0;
202204
ceph::real_time mtime;
203205
std::string etag;
204206
std::string owner;
205207
std::string owner_display_name;
206208
std::string content_type;
207-
uint64_t accounted_size;
209+
uint64_t accounted_size = 0;
208210
std::string user_data;
209211
std::string storage_class;
210-
bool appendable;
211-
212-
rgw_bucket_dir_entry_meta() :
213-
category(RGWObjCategory::None), size(0), accounted_size(0), appendable(false) { }
212+
bool appendable = false;
214213

215214
void encode(ceph::buffer::list &bl) const {
216215
ENCODE_START(7, 3, bl);
@@ -479,12 +478,10 @@ enum class BIIndexType : uint8_t {
479478
struct rgw_bucket_category_stats;
480479

481480
struct rgw_cls_bi_entry {
482-
BIIndexType type;
481+
BIIndexType type = BIIndexType::Invalid;
483482
std::string idx;
484483
ceph::buffer::list data;
485484

486-
rgw_cls_bi_entry() : type(BIIndexType::Invalid) {}
487-
488485
void encode(ceph::buffer::list& bl) const {
489486
ENCODE_START(1, 1, bl);
490487
encode(type, bl);
@@ -507,7 +504,7 @@ struct rgw_cls_bi_entry {
507504
void decode_json(JSONObj *obj, cls_rgw_obj_key *effective_key = NULL);
508505
static void generate_test_instances(std::list<rgw_cls_bi_entry*>& o);
509506
bool get_info(cls_rgw_obj_key *key, RGWObjCategory *category,
510-
rgw_bucket_category_stats *accounted_stats);
507+
rgw_bucket_category_stats *accounted_stats) const;
511508
};
512509
WRITE_CLASS_ENCODER(rgw_cls_bi_entry)
513510

src/rgw/driver/rados/rgw_rados.cc

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9247,17 +9247,6 @@ int RGWRados::bi_get(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_
92479247
return cls_rgw_bi_get(ref.ioctx, ref.obj.oid, index_type, key, entry);
92489248
}
92499249

9250-
int RGWRados::bi_get_vals(BucketShard& bs, set<string>& log_entries_wanted,
9251-
list<rgw_cls_bi_entry> *entries, optional_yield y)
9252-
{
9253-
auto& ref = bs.bucket_obj;
9254-
int ret = cls_rgw_bi_get_vals(ref.ioctx, ref.obj.oid, log_entries_wanted, entries);
9255-
if (ret < 0)
9256-
return ret;
9257-
9258-
return 0;
9259-
}
9260-
92619250
void RGWRados::bi_put(ObjectWriteOperation& op, BucketShard& bs, rgw_cls_bi_entry& entry, optional_yield y)
92629251
{
92639252
auto& ref = bs.bucket_obj;

src/rgw/driver/rados/rgw_rados.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1525,7 +1525,6 @@ class RGWRados
15251525
int bi_get_instance(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, rgw_bucket_dir_entry *dirent, optional_yield y);
15261526
int bi_get_olh(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, rgw_bucket_olh_entry *olh, optional_yield y);
15271527
int bi_get(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, const rgw_obj& obj, BIIndexType index_type, rgw_cls_bi_entry *entry, optional_yield y);
1528-
int bi_get_vals(BucketShard& bs, std::set<std::string>& log_entries_wanted, std::list<rgw_cls_bi_entry> *entries, optional_yield y);
15291528
void bi_put(librados::ObjectWriteOperation& op, BucketShard& bs, rgw_cls_bi_entry& entry, optional_yield y);
15301529
int bi_put(BucketShard& bs, rgw_cls_bi_entry& entry, optional_yield y);
15311530
int bi_put(const DoutPrefixProvider *dpp, rgw_bucket& bucket, rgw_obj& obj, rgw_cls_bi_entry& entry, optional_yield y);

0 commit comments

Comments
 (0)