From 57bee5fcb66c22af4f8a917a415856458c5f2d8c 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. Fixes: http://tracker.ceph.com/issues/22517 Signed-off-by: Adam C. Emerson (cherry picked from commit 1a3fcc70c0747791aa423cd0aa7d2596eaf3d73c) --- 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 0f5c74ce2222a..f48544ae7be6b 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -457,6 +457,37 @@ static 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.name); diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index ee01f32e79299..e4468d22a8af3 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -59,6 +59,7 @@ protected: int do_aws4_auth_completion(); virtual int init_quota(); + public: RGWOp() : s(nullptr), dialect_handler(nullptr), store(nullptr), cors_exist(false), op_ret(0) {} -- 2.39.5