*/
}
- if (!reads.empty()) {
+ /* If the read is not empty AND the object is not going tbe deleted as
+ * part of the op, then record that we need to do the reads. Potentially
+ * some performance could be gained by not calculating reads at all if
+ * delete_first is set, but this is not a performance-critical code path.
+ */
+ if (!reads.empty() && !op.delete_first) {
to_read = std::move(reads);
}
}
/* We also want to remove the std::nullopt entries since
* the keys already won't exist */
for (auto j = op.attr_updates.begin();
- j != op.attr_updates.end();
- ) {
+ j != op.attr_updates.end();) {
if (j->second) {
++j;
} else {
j = op.attr_updates.erase(j);
}
- }
+ }
/* Fill in all current entries for xattr rollback */
if (obc) {
xattr_rollback.insert(
ASSERT_EQ(ref_write, plan.will_write);
}
+TEST(ectransaction, delete_and_write_misaligned) {
+ hobject_t h;
+ PGTransaction::ObjectOperation op;
+ bufferlist a;
+ uint64_t new_size = 14 * (EC_ALIGN_SIZE / 4);
+
+ // We have a 4k write quite a way after the current limit of a 4k object
+ a.append_zero(new_size);
+ op.buffer_updates.insert(0, new_size, PGTransaction::ObjectOperation::BufferUpdate::Write{a, 0});
+ op.delete_first = true;
+
+ pg_pool_t pool;
+ pool.set_flag(pg_pool_t::FLAG_EC_OPTIMIZATIONS);
+ ECUtil::stripe_info_t sinfo(2, 1, 2 * EC_ALIGN_SIZE, &pool, std::vector<shard_id_t>(0));
+ object_info_t oi;
+ oi.size = new_size;
+ shard_id_set shards;
+ shards.insert_range(shard_id_t(0), 3);
+
+ ECTransaction::WritePlanObj plan(
+ h,
+ op,
+ sinfo,
+ shards,
+ shards,
+ false,
+ 16*EC_ALIGN_SIZE,
+ std::nullopt,
+ std::nullopt,
+ ECUtil::HashInfoRef(new ECUtil::HashInfo(1)),
+ nullptr,
+ 0);
+
+ generic_derr << "plan " << plan << dendl;
+
+ /* We are going to delete the object before writing it. Best not write anything
+ * from the old object... */
+ ASSERT_FALSE(plan.to_read);
+
+ // Writes should cover parity only.
+ ECUtil::shard_extent_set_t ref_write(sinfo.get_k_plus_m());
+ ref_write[shard_id_t(0)].insert(0, 2*EC_ALIGN_SIZE);
+ ref_write[shard_id_t(1)].insert(0, 2*EC_ALIGN_SIZE);
+ ref_write[shard_id_t(2)].insert(0, 2*EC_ALIGN_SIZE);
+ ASSERT_EQ(ref_write, plan.will_write);
+}
\ No newline at end of file