From 333f8d21ad16b340e9ecbc51dca5ea5b644376f7 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 13 Nov 2014 19:29:30 -0800 Subject: [PATCH] rgw: time out pending olh entries remove old pending entries Signed-off-by: Yehuda Sadeh --- src/common/config_opts.h | 2 ++ src/rgw/rgw_rados.cc | 69 ++++++++++++++++++++++++++++++++++++++++ src/rgw/rgw_rados.h | 2 ++ 3 files changed, 73 insertions(+) diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 08739c417205e..74f1b8cfc105c 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -951,6 +951,8 @@ OPTION(rgw_user_quota_sync_wait_time, OPT_INT, 3600 * 24) // min time between tw OPTION(rgw_multipart_min_part_size, OPT_INT, 5 * 1024 * 1024) // min size for each part (except for last one) in multipart upload +OPTION(rgw_olh_pending_timeout_sec, OPT_INT, 3600) // time until we retire a pending olh change + OPTION(mutex_perf_counter, OPT_BOOL, false) // enable/disable mutex perf counter OPTION(throttler_perf_counter, OPT_BOOL, true) // enable/disable throttler perf counter diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index ca57d19258bb4..e05c5bc35f4b9 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -5928,11 +5928,80 @@ int RGWRados::get_olh(rgw_obj& obj, RGWOLHInfo *olh) return 0; } +void RGWRados::check_pending_olh_entries(map& pending_entries, + map *rm_pending_entries) +{ + map::iterator iter = pending_entries.begin(); + + utime_t now = ceph_clock_now(cct); + + while (iter != pending_entries.end()) { + bufferlist::iterator biter = iter->second.begin(); + RGWOLHPendingInfo pending_info; + try { + ::decode(pending_info, biter); + } catch (buffer::error& err) { + /* skipping bad entry, we could remove it but it might hide a bug */ + ldout(cct, 0) << "ERROR: failed to decode pending entry " << iter->first << dendl; + ++iter; + continue; + } + + map::iterator cur_iter = iter; + ++iter; + if (now - pending_info.time >= cct->_conf->rgw_olh_pending_timeout_sec) { + (*rm_pending_entries)[cur_iter->first] = cur_iter->second; + pending_entries.erase(cur_iter); + } + } +} + +int RGWRados::remove_olh_pending_entries(RGWObjState& state, rgw_obj& olh_obj, map& pending_attrs) +{ + ObjectWriteOperation op; + + bucket_index_guard_olh_op(state, op); + + for (map::iterator iter = pending_attrs.begin(); iter != pending_attrs.end(); ++iter) { + op.rmxattr(iter->first.c_str()); + } + + rgw_rados_ref ref; + rgw_bucket bucket; + int r = get_obj_ref(olh_obj, &ref, &bucket); + if (r < 0) { + return r; + } + + /* update olh object */ + r = ref.ioctx.operate(ref.oid, &op); + if (r == -ENOENT || r == -ECANCELED) { + /* raced with some other change, shouldn't sweat about it */ + r = 0; + } + if (r < 0) { + ldout(cct, 0) << "ERROR: could not apply olh update, r=" << r << dendl; + return r; + } + + return 0; +} + int RGWRados::follow_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, rgw_obj& olh_obj, rgw_obj *target) { map pending_entries; filter_attrset(state->attrset, RGW_ATTR_OLH_PENDING_PREFIX, &pending_entries); + map rm_pending_entries; + check_pending_olh_entries(pending_entries, &rm_pending_entries); + + if (!rm_pending_entries.empty()) { + int ret = remove_olh_pending_entries(*state, olh_obj, rm_pending_entries); + if (ret < 0) { + ldout(cct, 20) << "ERROR: rm_pending_entries returned ret=" << ret << dendl; + return ret; + } + } if (!pending_entries.empty()) { ldout(cct, 20) << __func__ << "(): found pending entries, need to update_olh() on bucket=" << olh_obj.bucket << dendl; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 98da82ce3153e..a21e4c52e9496 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1728,6 +1728,8 @@ public: int set_olh(RGWObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& target_obj, bool delete_marker, rgw_bucket_dir_entry_meta *meta); int unlink_obj_instance(RGWObjectCtx& obj_ctx, const string& bucket_owner, rgw_obj& target_obj); + void check_pending_olh_entries(map& pending_entries, map *rm_pending_entries); + int remove_olh_pending_entries(RGWObjState& state, rgw_obj& olh_obj, map& pending_attrs); int follow_olh(RGWObjectCtx& ctx, RGWObjState *state, rgw_obj& olh_obj, rgw_obj *target); int get_olh(rgw_obj& obj, RGWOLHInfo *olh); -- 2.39.5