diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-02-17 23:11:42 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-03-12 18:18:11 +0100 |
commit | ece90d73c455278f66c29b06c1acf47e3701d7a7 (patch) | |
tree | 426977ae5682a6a7f7a06c64612fd1d2f8638384 | |
parent | 4a41de81694b6c986dab7e766787b201630bfde9 (diff) | |
download | systemd-ece90d73c455278f66c29b06c1acf47e3701d7a7.tar.gz |
journald: when we fail to add a new entry to a journal, return the seqno
Fixes: #18005
(cherry picked from commit 0eaee8281d4699903b8b2cce18c836d4a144aee3)
(cherry picked from commit 06cd0295b94a23ed879697752d85339f815a7788)
-rw-r--r-- | src/journal/journal-file.c | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 40fd2b2cca..5e17fd2eb2 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -994,31 +994,59 @@ int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset return 0; } -static uint64_t journal_file_entry_seqnum(JournalFile *f, uint64_t *seqnum) { - uint64_t r; +static uint64_t journal_file_entry_seqnum( + JournalFile *f, + uint64_t *seqnum) { + + uint64_t ret; assert(f); assert(f->header); - r = le64toh(f->header->tail_entry_seqnum) + 1; + /* Picks a new sequence number for the entry we are about to add and returns it. */ + + ret = le64toh(f->header->tail_entry_seqnum) + 1; if (seqnum) { - /* If an external seqnum counter was passed, we update - * both the local and the external one, and set it to - * the maximum of both */ + /* If an external seqnum counter was passed, we update both the local and the external one, + * and set it to the maximum of both */ - if (*seqnum + 1 > r) - r = *seqnum + 1; + if (*seqnum + 1 > ret) + ret = *seqnum + 1; - *seqnum = r; + *seqnum = ret; } - f->header->tail_entry_seqnum = htole64(r); + f->header->tail_entry_seqnum = htole64(ret); if (f->header->head_entry_seqnum == 0) - f->header->head_entry_seqnum = htole64(r); + f->header->head_entry_seqnum = htole64(ret); - return r; + return ret; +} + +static void journal_file_revert_entry_seqnum( + JournalFile *f, + uint64_t *seqnum, + uint64_t revert_seqnum) { + + assert(f); + assert(f->header); + + if (revert_seqnum == 0) /* sequence number 0? can't go back */ + return; + + /* Undoes the effect of journal_file_entry_seqnum() above: if we fail to append an entry to a file, + * let's revert the seqnum we were about to use, so that we can use it on the next entry. */ + + if (le64toh(f->header->tail_entry_seqnum) == revert_seqnum) + f->header->tail_entry_seqnum = htole64(revert_seqnum - 1); + + if (le64toh(f->header->head_entry_seqnum) == revert_seqnum) + f->header->head_entry_seqnum = 0; + + if (seqnum && *seqnum == revert_seqnum) + *seqnum = revert_seqnum - 1; } int journal_file_append_object( @@ -1982,12 +2010,12 @@ static int journal_file_append_entry_internal( #if HAVE_GCRYPT r = journal_file_hmac_put_object(f, OBJECT_ENTRY, o, np); if (r < 0) - return r; + goto fail; #endif r = journal_file_link_entry(f, o, np); if (r < 0) - return r; + goto fail; if (ret) *ret = o; @@ -1996,6 +2024,10 @@ static int journal_file_append_entry_internal( *ret_offset = np; return 0; + +fail: + journal_file_revert_entry_seqnum(f, seqnum, le64toh(o->entry.seqnum)); + return r; } void journal_file_post_change(JournalFile *f) { |