diff --git a/src/knot/server/journal.c b/src/knot/server/journal.c index e12aefaea85d8e83a60afd92ee1899a31170a1bb..1a8194bcef97fad1d234e34ab980d359731f834b 100644 --- a/src/knot/server/journal.c +++ b/src/knot/server/journal.c @@ -388,7 +388,7 @@ static int journal_open_file(journal_t *j) /* Get journal file size. */ struct stat st; - if (stat(j->path, &st) < 0) { + if (fstat(j->fd, &st) < 0) { dbg_journal_verb("journal: cannot get journal fsize\n"); goto open_file_error; } @@ -548,7 +548,11 @@ int journal_write_in(journal_t *j, journal_node_t **rn, uint64_t id, size_t len) (unsigned long long)id, j->qtail, len, j->fsize); /* Calculate remaining bytes to reach file size limit. */ - size_t fs_remaining = j->fslimit - j->fsize; + size_t fs_remaining = 0; + if (j->fsize < j->fslimit) { + fs_remaining = j->fslimit - j->fsize; + } + int seek_ret = 0; /* Increase free segment if on the end of file. */ diff --git a/tests/journal.c b/tests/journal.c index 08279d9958a75461b8716bdead4c0dc78fa6ee9b..eaf58ef41e1421bc01a0d62ed8557f95494a9dad 100644 --- a/tests/journal.c +++ b/tests/journal.c @@ -19,6 +19,7 @@ #include <stdio.h> #include <limits.h> #include <unistd.h> +#include <sys/stat.h> #include <tap/basic.h> #include "knot/server/journal.h" @@ -37,7 +38,7 @@ static int randstr(char* dst, size_t len) int main(int argc, char *argv[]) { - plan(10); + plan_lazy(); /* Create tmpdir */ int fsize = 10 * 1024 * 1024; @@ -113,6 +114,33 @@ int main(int argc, char *argv[]) } is_int(KNOT_EOK, ret, "journal: sustained mmap r/w"); + /* Overfill */ + ret = journal_map(journal, chk_key, &mptr, fsize, false); + is_int(KNOT_ESPACE, ret, "journal: overfill"); + + /* Fillup */ + tskey = 0xBEEF0000; + size_t large_entry_len = 512 * 1024; + char *large_entry = malloc(512 * 1024); + assert(large_entry); + randstr(large_entry, large_entry_len); + for (int i = 0; i < 512; ++i) { + chk_key = tskey + i; + ret = journal_map(journal, chk_key, &mptr, large_entry_len, false); + if (ret != KNOT_EOK) { + break; + } + + journal_unmap(journal, chk_key, mptr, 1); + } + is_int(KNOT_EBUSY, ret, "journal: fillup"); + free(large_entry); + + /* Check file size. */ + struct stat st; + stat(journal->path, &st); + ok(st.st_size < fsize + large_entry_len, "journal: fillup file size check"); + /* Close journal. */ journal_close(journal);