From 3805ea635a5f28656072b2cf5cdc9b5bf53b5e97 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Fri, 5 Apr 2019 09:26:05 -0400 Subject: [PATCH] rgw: limit entries in remove_olh_pending_entries() If there are too many entries to send in a single osd op, the osd rejects the request with EINVAL. This error happens in follow_olh(), which means that requests against the object logical head (requests with no version id) can't be resolved to the current object version. In multisite, this also causes data sync to get stuck in retries Fixes: http://tracker.ceph.com/issues/39118 Signed-off-by: Casey Bodley --- src/rgw/rgw_rados.cc | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 12ea55de16f..a99415efe5e 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -7809,31 +7809,34 @@ void RGWRados::check_pending_olh_entries(map& pending_entrie int RGWRados::remove_olh_pending_entries(const RGWBucketInfo& bucket_info, RGWObjState& state, const 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; int r = get_obj_head_ref(bucket_info, olh_obj, &ref); if (r < 0) { return r; } - /* update olh object */ - r = ref.ioctx.operate(ref.obj.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; - } + // trim no more than 1000 entries per osd op + constexpr int max_entries = 1000; + + auto i = pending_attrs.begin(); + while (i != pending_attrs.end()) { + ObjectWriteOperation op; + bucket_index_guard_olh_op(state, op); + for (int n = 0; n < max_entries && i != pending_attrs.end(); ++n, ++i) { + op.rmxattr(i->first.c_str()); + } + + r = ref.ioctx.operate(ref.obj.oid, &op); + if (r == -ENOENT || r == -ECANCELED) { + /* raced with some other change, shouldn't sweat about it */ + return 0; + } + if (r < 0) { + ldout(cct, 0) << "ERROR: could not apply olh update, r=" << r << dendl; + return r; + } + } return 0; } -- 2.39.5