From dea29460ed513f965de2dcac9e29180b06d56b58 Mon Sep 17 00:00:00 2001 From: "Adam C. Emerson" Date: Fri, 17 Nov 2017 15:51:42 -0500 Subject: [PATCH] rgw: Add retry_raced_bucket_write If the OSD informs us that our bucket info is out of date when we need to write, we should have a way to update it. This template function allows us to wrap relevant sections of code so they'll be retried against new bucket info on -ECANCELED. Signed-off-by: Adam C. Emerson (cherry picked from commit 1a3fcc70c0747791aa423cd0aa7d2596eaf3d73c) Fixes: http://tracker.ceph.com/issues/22517 --- src/rgw/rgw_op.cc | 31 +++++++++++++++++++++++++++++++ src/rgw/rgw_op.h | 1 + 2 files changed, 32 insertions(+) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 11fdbd4ebc3fd..15bd3baa877ba 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -647,6 +647,37 @@ void rgw_bucket_object_pre_exec(struct req_state *s) dump_bucket_from_state(s); } +// So! Now and then when we try to update bucket information, the +// bucket has changed during the course of the operation. (Or we have +// a cache consistency problem that Watch/Notify isn't ruling out +// completely.) +// +// When this happens, we need to update the bucket info and try +// again. We have, however, to try the right *part* again. We can't +// simply re-send, since that will obliterate the previous update. +// +// Thus, callers of this function should include everything that +// merges information to be changed into the bucket information as +// well as the call to set it. +// +// The called function must return an integer, negative on error. In +// general, they should just return op_ret. +namespace { +template +int retry_raced_bucket_write(RGWRados* g, req_state* s, const F& f) { + auto r = f(); + for (auto i = 0u; i < 15u && r == -ECANCELED; ++i) { + r = g->try_refresh_bucket_info(s->bucket_info, nullptr, + &s->bucket_attrs); + if (r >= 0) { + r = f(); + } + } + return r; +} +} + + int RGWGetObj::verify_permission() { obj = rgw_obj(s->bucket, s->object); diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 68b83a45f1338..1db3521ab00c4 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -120,6 +120,7 @@ protected: int do_aws4_auth_completion(); virtual int init_quota(); + public: RGWOp() : s(nullptr), -- 2.39.5