]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
erasure-code: ensure that coding chunks are page aligned
authorLoic Dachary <loic@dachary.org>
Wed, 8 Jan 2014 19:13:37 +0000 (20:13 +0100)
committerLoic Dachary <loic@dachary.org>
Wed, 8 Jan 2014 19:13:37 +0000 (20:13 +0100)
When coding chunks are allocated for jerasure, their address must be
aligned to page boundaries. The requirement is actually to be aligned on
a long long boundary but bufferlist do not allow for fine tuning of the
alignment.

If padding is necessary because the total size of the data to be encoded
is not a multiple of the alignment requirements as returned by
get_alignment(), the buffer is not only padded but also rebuilt using
rebuild_page_aligned() to preserve the page alignment that is expected
of the input buffer.

The overhead of rebuilding the whole input buffer when padding is
necessary could be reduced by only reallocating one buffer for the last
data chunk, therefore reducing the amount of data being copied. However,
this optimization is not going to be used if the caller takes care of
the padding, which is likely to be the case most of the time.

Signed-off-by: Loic Dachary <loic@dachary.org>
src/osd/ErasureCodePluginJerasure/ErasureCodeJerasure.cc

index fe656e58ee00f3a109b8a4bcff5fe08574711928..ac8bcc242efd655808197175d615a8fef363d5f9 100644 (file)
@@ -82,12 +82,17 @@ int ErasureCodeJerasure::encode(const set<int> &want_to_encode,
   dout(10) << "encode adjusted buffer length from " << in.length()
           << " to " << padded_length << dendl;
   assert(padded_length % k == 0);
-  unsigned blocksize = padded_length / k;
-  unsigned length = blocksize * ( k + m );
   bufferlist out(in);
-  bufferptr pad(length - in.length());
-  pad.zero(0, padded_length - in.length());
-  out.push_back(pad);
+  if (padded_length - in.length() > 0) {
+    bufferptr pad(padded_length - in.length());
+    pad.zero();
+    out.push_back(pad);
+    out.rebuild_page_aligned();
+  }
+  unsigned blocksize = padded_length / k;
+  unsigned coding_length = blocksize * m;
+  bufferptr coding(buffer::create_page_aligned(coding_length));
+  out.push_back(coding);
   char *chunks[k + m];
   for (int i = 0; i < k + m; i++) {
     bufferlist &chunk = (*encoded)[i];