Skip to content
Snippets Groups Projects
Commit 4a21001f authored by Jan Včelák's avatar Jan Včelák :rocket:
Browse files

Merge branch 'journal_file_end_check' into 'master'

Correct detection of journal end position.

MR !316
parents a108c815 1b07a798
Branches
Tags
No related merge requests found
...@@ -483,10 +483,10 @@ int journal_write_in(journal_t *j, journal_node_t **rn, uint64_t id, size_t len) ...@@ -483,10 +483,10 @@ int journal_write_in(journal_t *j, journal_node_t **rn, uint64_t id, size_t len)
dbg_journal("journal: will write id=%llu, node=%u, size=%zu, fsize=%zu\n", dbg_journal("journal: will write id=%llu, node=%u, size=%zu, fsize=%zu\n",
(unsigned long long)id, j->qtail, len, j->fsize); (unsigned long long)id, j->qtail, len, j->fsize);
/* Calculate remaining bytes to reach file size limit. */ /* Calculate file end position (with imposed limits). */
size_t fs_remaining = 0; size_t file_end = j->fsize;
if (j->fsize < j->fslimit) { if (file_end > j->fslimit) {
fs_remaining = j->fslimit - j->fsize; file_end = j->fslimit;
} }
int seek_ret = 0; int seek_ret = 0;
...@@ -495,12 +495,12 @@ int journal_write_in(journal_t *j, journal_node_t **rn, uint64_t id, size_t len) ...@@ -495,12 +495,12 @@ int journal_write_in(journal_t *j, journal_node_t **rn, uint64_t id, size_t len)
dbg_journal("journal: free.pos = %u free.len = %u\n", dbg_journal("journal: free.pos = %u free.len = %u\n",
j->free.pos, j->free.len); j->free.pos, j->free.len);
journal_node_t *n = j->nodes + j->qtail; journal_node_t *n = j->nodes + j->qtail;
if (j->free.pos + j->free.len == j->fsize) { if (j->free.pos + len >= file_end) {
dbg_journal_verb("journal: * is last node\n"); dbg_journal_verb("journal: * is last node\n");
/* Grow journal file until the size limit. */ /* Grow journal file until the size limit. */
if(j->free.len < len && len <= fs_remaining) { if(j->free.pos + len < j->fslimit) {
size_t diff = len - j->free.len; size_t diff = len - j->free.len;
dbg_journal("journal: * growing by +%zu, pos=%u, " dbg_journal("journal: * growing by +%zu, pos=%u, "
"new fsize=%zu\n", "new fsize=%zu\n",
...@@ -509,10 +509,8 @@ int journal_write_in(journal_t *j, journal_node_t **rn, uint64_t id, size_t len) ...@@ -509,10 +509,8 @@ int journal_write_in(journal_t *j, journal_node_t **rn, uint64_t id, size_t len)
j->fsize += diff; /* Appending increases file size. */ j->fsize += diff; /* Appending increases file size. */
j->free.len += diff; j->free.len += diff;
} } else {
/* Rewind if resize is needed, but the limit is reached. */
/* Rewind if resize is needed, but the limit is reached. */
if(j->free.len < len && len > fs_remaining) {
journal_node_t *head = j->nodes + j->qhead; journal_node_t *head = j->nodes + j->qhead;
j->fsize = j->free.pos; j->fsize = j->free.pos;
j->free.pos = head->pos; j->free.pos = head->pos;
......
...@@ -36,17 +36,18 @@ static int randstr(char* dst, size_t len) ...@@ -36,17 +36,18 @@ static int randstr(char* dst, size_t len)
} }
/*! \brief Journal fillup test with size check. */ /*! \brief Journal fillup test with size check. */
static void test_fillup(journal_t *journal, int fsize, const char *note) static void test_fillup(journal_t *journal, size_t fsize, unsigned iter)
{ {
const int chunk = 512 + rand() % 512; const unsigned chunk = 512 + rand() % 512;
int ret = KNOT_EOK; int ret = KNOT_EOK;
char *mptr = NULL; char *mptr = NULL;
size_t large_entry_len = chunk * 1024; size_t large_entry_len = chunk * 1024;
char *large_entry = malloc(chunk * 1024); char *large_entry = malloc(chunk * 1024);
assert(large_entry); assert(large_entry);
randstr(large_entry, large_entry_len); randstr(large_entry, large_entry_len);
for (int i = 0; i < chunk; ++i) { unsigned i = 0;
uint64_t chk_key = (uint64_t)journal + i; for (; i < 512; ++i) {
uint64_t chk_key = 0xBEBE + (iter * 512) + i;
ret = journal_map(journal, chk_key, &mptr, large_entry_len, false); ret = journal_map(journal, chk_key, &mptr, large_entry_len, false);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
break; break;
...@@ -55,13 +56,16 @@ static void test_fillup(journal_t *journal, int fsize, const char *note) ...@@ -55,13 +56,16 @@ static void test_fillup(journal_t *journal, int fsize, const char *note)
memcpy(mptr, large_entry, large_entry_len); memcpy(mptr, large_entry, large_entry_len);
journal_unmap(journal, chk_key, mptr, 1); journal_unmap(journal, chk_key, mptr, 1);
} }
is_int(KNOT_EBUSY, ret, "journal: %s fillup", note); is_int(KNOT_EBUSY, ret, "journal: fillup #%u (%d entries)", iter, i);
free(large_entry); free(large_entry);
/* Check file size. */ /* Check file size. */
struct stat st; struct stat st;
fstat(journal->fd, &st); fstat(journal->fd, &st);
ok(st.st_size < fsize + large_entry_len, "journal: %s fillup file size check", note); ok(st.st_size < fsize + large_entry_len, "journal: fillup / size check #%u", iter);
if (st.st_size > fsize + large_entry_len) {
diag("journal: fillup / size check #%u fsize(%zu) > max(%zu)", iter, st.st_size, fsize + large_entry_len);
}
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
...@@ -69,7 +73,7 @@ int main(int argc, char *argv[]) ...@@ -69,7 +73,7 @@ int main(int argc, char *argv[])
plan_lazy(); plan_lazy();
/* Create tmpdir */ /* Create tmpdir */
int fsize = 10 * 1024 * 1024; size_t fsize = 10 * 1024 * 1024;
char *tmpdir = test_tmpdir(); char *tmpdir = test_tmpdir();
char jfilename[256]; char jfilename[256];
snprintf(jfilename, sizeof(jfilename), "%s/%s", tmpdir, "journal.XXXXXX"); snprintf(jfilename, sizeof(jfilename), "%s/%s", tmpdir, "journal.XXXXXX");
...@@ -146,18 +150,19 @@ int main(int argc, char *argv[]) ...@@ -146,18 +150,19 @@ int main(int argc, char *argv[])
is_int(KNOT_ESPACE, ret, "journal: overfill"); is_int(KNOT_ESPACE, ret, "journal: overfill");
/* Fillup */ /* Fillup */
test_fillup(journal, fsize, "iter#1"); unsigned iterations = 10;
for (unsigned i = 0; i < iterations; ++i) {
/* Journal flush. */
journal_close(journal);
ret = journal_mark_synced(jfilename);
is_int(KNOT_EOK, ret, "journal: flush after fillup #%u", i);
journal = journal_open(jfilename, fsize);
ok(journal != NULL, "journal: reopen after flush #%u", i);
/* Journal fillup. */
test_fillup(journal, fsize, i);
}
/* Journal flush + refill. */
journal_close(journal);
ret = journal_mark_synced(jfilename);
is_int(KNOT_EOK, ret, "journal: flush after fillup");
journal = journal_open(jfilename, fsize);
ok(journal != NULL, "journal: reopen after flush");
/* Fillup */
test_fillup(journal, fsize, "iter#2");
/* Close journal. */ /* Close journal. */
journal_close(journal); journal_close(journal);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment