From: Adam C. Emerson Date: Fri, 17 Nov 2017 20:51:42 +0000 (-0500) Subject: rgw: Add retry_raced_bucket_write X-Git-Tag: v13.0.1~61^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1a3fcc70c0747791aa423cd0aa7d2596eaf3d73c;p=ceph.git 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 --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 4003bea61ff9..d0404f77fa0d 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -630,6 +630,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 1cb44d2c48e0..22fe2e7ffdb0 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),