From 989793d341e730f452175fa18cf0f7ef4529d62c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 12 Oct 2016 12:36:01 +0200 Subject: journal: when iterating through entry arrays and we hit an invalid one keep going When iterating through partially synced journal files we need to be prepared for hitting with invalid entries (specifically: non-initialized). Instead of generated an error and giving up, let's simply try to preceed with the next one that is valid (and debug log about this). This reworks the logic introduced with caeab8f626e709569cc492b75eb7e119076059e7 to iteration in both directions, and tries to look for valid entries located after the invalid one. It also extends the behaviour to both iterating through the global entry array and per-data object entry arrays. Fixes: #4088 --- src/journal/journal-file.c | 54 ++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 3f1afdaf1f..e26c8223d8 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -2555,18 +2555,24 @@ int journal_file_next_entry( } /* And jump to it */ - r = generic_array_get(f, - le64toh(f->header->entry_array_offset), - i, - ret, &ofs); - if (r == -EBADMSG && direction == DIRECTION_DOWN) { - /* Special case: when we iterate throught the journal file linearly, and hit an entry we can't read, - * consider this the end of the journal file. */ - log_debug_errno(r, "Encountered entry we can't read while iterating through journal file. Considering this the end of the file."); - return 0; + for (;;) { + r = generic_array_get(f, + le64toh(f->header->entry_array_offset), + i, + ret, &ofs); + if (r > 0) + break; + if (r != -EBADMSG) + return r; + + /* OK, so this entry is borked. Most likely some entry didn't get synced to disk properly, let's see if + * the next one might work for us instead. */ + log_debug_errno(r, "Entry item %" PRIu64 " is bad, skipping over it.", i); + + r = bump_array_index(&i, direction, n); + if (r <= 0) + return r; } - if (r <= 0) - return r; /* Ensure our array is properly ordered. */ if (p > 0 && !check_properly_ordered(ofs, p, direction)) { @@ -2588,8 +2594,8 @@ int journal_file_next_entry_for_data( Object **ret, uint64_t *offset) { uint64_t i, n, ofs; - int r; Object *d; + int r; assert(f); assert(p > 0 || !o); @@ -2626,13 +2632,23 @@ int journal_file_next_entry_for_data( return r; } - r = generic_array_get_plus_one(f, - le64toh(d->data.entry_offset), - le64toh(d->data.entry_array_offset), - i, - ret, &ofs); - if (r <= 0) - return r; + for (;;) { + r = generic_array_get_plus_one(f, + le64toh(d->data.entry_offset), + le64toh(d->data.entry_array_offset), + i, + ret, &ofs); + if (r > 0) + break; + if (r != -EBADMSG) + return r; + + log_debug_errno(r, "Data entry item %" PRIu64 " is bad, skipping over it.", i); + + r = bump_array_index(&i, direction, n); + if (r <= 0) + return r; + } /* Ensure our array is properly ordered. */ if (p > 0 && check_properly_ordered(ofs, p, direction)) { -- cgit v1.2.3-54-g00ecf