Blame SOURCES/0344-journal-verify-don-t-hit-SIGFPE-when-determining-pro.patch

17b0f1
From 1466d84c159c1a9d1839c1b346906b722e6311a3 Mon Sep 17 00:00:00 2001
17b0f1
From: Lennart Poettering <lennart@poettering.net>
17b0f1
Date: Fri, 24 Jul 2015 01:40:44 +0200
17b0f1
Subject: [PATCH] journal-verify: don't hit SIGFPE when determining progress
17b0f1
17b0f1
If we determine the progress based on a number of objects available,
17b0f1
don't blindly devide by the number of objects, given that it might be 0.
17b0f1
17b0f1
Cherry-picked from: 45c047b227d96e98e7076c15ae774ff6390dc403
17b0f1
Related: #1350232
17b0f1
---
17b0f1
 src/journal/journal-verify.c | 16 +++++++++++++---
17b0f1
 1 file changed, 13 insertions(+), 3 deletions(-)
17b0f1
17b0f1
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
17b0f1
index b03335ef31..983217c1bc 100644
17b0f1
--- a/src/journal/journal-verify.c
17b0f1
+++ b/src/journal/journal-verify.c
17b0f1
@@ -69,6 +69,16 @@ static void draw_progress(uint64_t p, usec_t *last_usec) {
17b0f1
         fflush(stdout);
17b0f1
 }
17b0f1
 
17b0f1
+static uint64_t scale_progress(uint64_t scale, uint64_t p, uint64_t m) {
17b0f1
+
17b0f1
+        /* Calculates scale * p / m, but handles m == 0 safely, and saturates */
17b0f1
+
17b0f1
+        if (p >= m || m == 0)
17b0f1
+                return scale;
17b0f1
+
17b0f1
+        return scale * p / m;
17b0f1
+}
17b0f1
+
17b0f1
 static void flush_progress(void) {
17b0f1
         unsigned n, i;
17b0f1
 
17b0f1
@@ -584,7 +594,7 @@ static int verify_hash_table(
17b0f1
                 uint64_t last = 0, p;
17b0f1
 
17b0f1
                 if (show_progress)
17b0f1
-                        draw_progress(0xC000 + (0x3FFF * i / n), last_usec);
17b0f1
+                        draw_progress(0xC000 + scale_progress(0x3FFF, i, n), last_usec);
17b0f1
 
17b0f1
                 p = le64toh(f->data_hash_table[i].head_hash_offset);
17b0f1
                 while (p != 0) {
17b0f1
@@ -726,7 +736,7 @@ static int verify_entry_array(
17b0f1
                 Object *o;
17b0f1
 
17b0f1
                 if (show_progress)
17b0f1
-                        draw_progress(0x8000 + (0x3FFF * i / n), last_usec);
17b0f1
+                        draw_progress(0x8000 + scale_progress(0x3FFF, i, n), last_usec);
17b0f1
 
17b0f1
                 if (a == 0) {
17b0f1
                         error(a, "array chain too short at %"PRIu64" of %"PRIu64, i, n);
17b0f1
@@ -863,7 +873,7 @@ int journal_file_verify(
17b0f1
         p = le64toh(f->header->header_size);
17b0f1
         while (p != 0) {
17b0f1
                 if (show_progress)
17b0f1
-                        draw_progress(0x7FFF * p / le64toh(f->header->tail_object_offset), &last_usec);
17b0f1
+                        draw_progress(scale_progress(0x7FFF, p, le64toh(f->header->tail_object_offset)), &last_usec);
17b0f1
 
17b0f1
                 r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &o);
17b0f1
                 if (r < 0) {