ReplicatedPG: ensure that ec appends are aligned

When not writing out the last chunk, _write_copy_chunk
will trim the chunk to a stripe boundary for ec pools
and adjust cursor.data_offset to compensate.

Signed-off-by: Samuel Just <sam.just@inktank.com>
This commit is contained in:
Samuel Just 2014-02-19 14:26:51 -08:00
parent 78d9c0072b
commit 715cbd3105
2 changed files with 32 additions and 1 deletions

View File

@ -5379,7 +5379,7 @@ void ReplicatedPG::_copy_some(ObjectContextRef obc, CopyOpRef cop)
// it already!
assert(cop->cursor.is_initial());
}
op.copy_get(&cop->cursor, cct->_conf->osd_copyfrom_max_chunk,
op.copy_get(&cop->cursor, get_copy_chunk_size(),
&cop->results.object_size, &cop->results.mtime,
&cop->results.category,
&cop->attrs, &cop->data, &cop->omap_header, &cop->omap,
@ -5509,6 +5509,27 @@ void ReplicatedPG::_write_copy_chunk(CopyOpRef cop, PGBackend::PGTransaction *t)
cop->attrs.clear();
}
if (!cop->temp_cursor.data_complete) {
assert(cop->data.length() + cop->temp_cursor.data_offset ==
cop->cursor.data_offset);
if (pool.info.requires_aligned_append() &&
!cop->cursor.data_complete) {
/**
* Trim off the unaligned bit at the end, we'll adjust cursor.data_offset
* to pick it up on the next pass.
*/
assert(cop->temp_cursor.data_offset %
pool.info.required_alignment() == 0);
if (cop->data.length() % pool.info.required_alignment() != 0) {
uint64_t to_trim =
cop->data.length() % pool.info.required_alignment();
bufferlist bl;
bl.substr_of(cop->data, 0, cop->data.length() - to_trim);
cop->data.swap(bl);
cop->cursor.data_offset -= to_trim;
assert(cop->data.length() + cop->temp_cursor.data_offset ==
cop->cursor.data_offset);
}
}
t->append(
cop->results.temp_oid,
cop->temp_cursor.data_offset,

View File

@ -1119,6 +1119,16 @@ protected:
bool mirror_snapset);
void process_copy_chunk(hobject_t oid, tid_t tid, int r);
void _write_copy_chunk(CopyOpRef cop, PGBackend::PGTransaction *t);
uint64_t get_copy_chunk_size() const {
uint64_t size = cct->_conf->osd_copyfrom_max_chunk;
if (pool.info.requires_aligned_append()) {
uint64_t alignment = pool.info.required_alignment();
if (size % alignment) {
size += alignment - (size % alignment);
}
}
return size;
}
void _copy_some(ObjectContextRef obc, CopyOpRef cop);
void _build_finish_copy_transaction(CopyOpRef cop,
PGBackend::PGTransaction *t);