Bug #8121
Updated by David Zafman about 10 years ago
I noticed that the existing code in build_push_op() may not handle all scenarios of fixing data_included interval when a short read happens. It only adjusts the current interval length. If the read was 0 bytes then the interval could be left with a 0 length instead of being removed. Also, additional intervals are left beyond the short read. Another possibility is that a short read should just assert because an inconsistency has been found. This is the untested code for fixing the data_included handling <pre> diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 8910e00..400be80 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -8289,8 +8289,19 @@ int ReplicatedBackend::build_push_op(const ObjectRecoveryInfo &recovery_info, dout(10) << " extent " << p.get_start() << "~" << p.get_len() << " is actually " << p.get_start() << "~" << bit.length() << dendl; - p.set_len(bit.length()); + interval_set<uint64_t>::iterator save = p++; + if (bit.length() == 0) + out_op->data_included.erase(save); //Remove this empty interval + else + save.set_len(bit.length()); + // Remove any other intervals present + while (p != out_op->data_included.end()) { + interval_set<uint64_t>::iterator save = p++; + out_op->data_included.erase(save); + } new_progress.data_complete = true; + out_op->data.claim_append(bit); + break; } out_op->data.claim_append(bit); } </pre>