]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journal: Tolerate lost tail hash chain nodes
authorChris Down <chris@chrisdown.name>
Thu, 18 Jun 2026 07:07:04 +0000 (16:07 +0900)
committerChris Down <chris@chrisdown.name>
Thu, 25 Jun 2026 15:06:47 +0000 (00:06 +0900)
The data and field hash table chains have the same problem the previous
commit fixed for entry array chains. New data and field objects are
linked at the tail of their hash bucket by patching the previous tail
object's next_hash_offset in place, so after a crash a persisted
predecessor (or the bucket head) can point at an object whose body never
reached disk.

journal_file_find_data_object_with_hash() and
journal_file_find_field_object_with_hash() walk those chains while
resolving matches, and on -EADDRNOTAVAIL/-EBADMSG from
journal_file_move_to_object() they simply return the error directly.
That propagates up to real_journal_next(), which discards the whole file
from the query.

Give those two lookups the same tolerance: on a read-only file, treat an
unreadable chain node as the end of the bucket chain.

src/libsystemd/sd-journal/journal-file.c

index b2ee3626840b1abe2de79ac09a047b8204580f30..087b0c3abc7f3c7af0804137366514802aa1a8b7 100644 (file)
@@ -1595,6 +1595,8 @@ int journal_file_find_field_object_with_hash(
                 Object *o;
 
                 r = journal_file_move_to_object(f, OBJECT_FIELD, p, &o);
+                if (chain_tail_lost(f, r, p, OBJECT_FIELD))
+                        break;
                 if (r < 0)
                         return r;
 
@@ -1696,6 +1698,8 @@ int journal_file_find_data_object_with_hash(
                 size_t rsize;
 
                 r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+                if (chain_tail_lost(f, r, p, OBJECT_DATA))
+                        break;
                 if (r < 0)
                         return r;