Skip to content

Commit

Permalink
rgw: limit entries in remove_olh_pending_entries()
Browse files Browse the repository at this point in the history
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 <cbodley@redhat.com>
(cherry picked from commit 3805ea6)
  • Loading branch information
cbodley authored and Prashant D committed Apr 18, 2019
1 parent d947e80 commit 4f813d2
Showing 1 changed file with 21 additions and 18 deletions.
39 changes: 21 additions & 18 deletions src/rgw/rgw_rados.cc
Expand Up @@ -7778,31 +7778,34 @@ void RGWRados::check_pending_olh_entries(map<string, bufferlist>& pending_entrie

int RGWRados::remove_olh_pending_entries(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, map<string, bufferlist>& pending_attrs)
{
ObjectWriteOperation op;

bucket_index_guard_olh_op(state, op);

for (map<string, bufferlist>::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;
}

Expand Down

0 comments on commit 4f813d2

Please sign in to comment.