]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osdc/Journaler: improved error handling
authorJohn Spray <john.spray@redhat.com>
Thu, 19 Mar 2015 20:16:55 +0000 (20:16 +0000)
committerJohn Spray <john.spray@redhat.com>
Mon, 23 Mar 2015 18:20:10 +0000 (18:20 +0000)
Exceptions from ::decode are caught and turned
into return codes that we can handle via
the contexts used for completions.

The assertion that entry_size != 0 is removed in
JournalStream::read so that if it is zero that
just becomes a normal deserialization error
later when someone tries to decode the
zerolength journal event.

Signed-off-by: John Spray <john.spray@redhat.com>
src/osdc/Journaler.cc

index a8712e622e58d2d68802acda6d459190d5b28071..5b33eedd2a92e6882d9167e9a8bb094331854c68 100644 (file)
@@ -202,14 +202,22 @@ void Journaler::_finish_reread_head(int r, bufferlist& bl, Context *finish)
   assert(bl.length() || r < 0 );
 
   // unpack header
-  Header h;
-  bufferlist::iterator p = bl.begin();
-  ::decode(h, p);
-  prezeroing_pos = prezero_pos = write_pos = flush_pos = safe_pos = h.write_pos;
-  expire_pos = h.expire_pos;
-  trimmed_pos = trimming_pos = h.trimmed_pos;
-  init_headers(h);
-  state = STATE_ACTIVE;
+  if (r == 0) {
+    Header h;
+    bufferlist::iterator p = bl.begin();
+    try {
+      ::decode(h, p);
+    } catch (const buffer::error &e) {
+      finish->complete(-EINVAL);
+      return;
+    }
+    prezeroing_pos = prezero_pos = write_pos = flush_pos = safe_pos = h.write_pos;
+    expire_pos = h.expire_pos;
+    trimmed_pos = trimming_pos = h.trimmed_pos;
+    init_headers(h);
+    state = STATE_ACTIVE;
+  }
+
   finish->complete(r);
 }
 
@@ -238,17 +246,21 @@ void Journaler::_finish_read_head(int r, bufferlist& bl)
   } 
 
   // unpack header
+  bool corrupt = false;
   Header h;
   bufferlist::iterator p = bl.begin();
-  ::decode(h, p);
-
-  bool corrupt = false;
-  if (h.magic != magic) {
-    ldout(cct, 0) << "on disk magic '" << h.magic << "' != my magic '"
-           << magic << "'" << dendl;
-    corrupt = true;
-  } else if (h.write_pos < h.expire_pos || h.expire_pos < h.trimmed_pos) {
-    ldout(cct, 0) << "Corrupt header (bad offsets): " << h << dendl;
+  try {
+    ::decode(h, p);
+
+    if (h.magic != magic) {
+      ldout(cct, 0) << "on disk magic '" << h.magic << "' != my magic '"
+              << magic << "'" << dendl;
+      corrupt = true;
+    } else if (h.write_pos < h.expire_pos || h.expire_pos < h.trimmed_pos) {
+      ldout(cct, 0) << "Corrupt header (bad offsets): " << h << dendl;
+      corrupt = true;
+    }
+  } catch (const buffer::error &e) {
     corrupt = true;
   }
 
@@ -1058,9 +1070,15 @@ bool Journaler::try_read_entry(bufferlist& bl)
   }
 
   uint64_t start_ptr;
-  size_t consumed = journal_stream.read(read_buf, &bl, &start_ptr);
-  if (stream_format >= JOURNAL_FORMAT_RESILIENT) {
-    assert(start_ptr == read_pos);
+  size_t consumed;
+  try {
+    consumed = journal_stream.read(read_buf, &bl, &start_ptr);
+    if (stream_format >= JOURNAL_FORMAT_RESILIENT) {
+      assert(start_ptr == read_pos);
+    }
+  } catch (const buffer::error &e) {
+    error = -EINVAL;
+    return false;
   }
 
   ldout(cct, 10) << "try_read_entry at " << read_pos << " read " 
@@ -1271,7 +1289,6 @@ size_t JournalStream::read(bufferlist &from, bufferlist *entry, uint64_t *start_
     assert(entry_sentinel == sentinel);
   }
   ::decode(entry_size, from_ptr);
-  assert(entry_size != 0);
 
   // Read out the payload
   from_ptr.copy(entry_size, *entry);