New store - write header on init only after clearing metadata

This commit is contained in:
Vitaliy Filippov
2026-06-13 19:56:06 +03:00
parent 677e755e4e
commit 33d14061d6
2 changed files with 48 additions and 42 deletions
+47 -42
View File
@@ -10,7 +10,6 @@
#define INIT_META_EMPTY 0 #define INIT_META_EMPTY 0
#define INIT_META_READING 1 #define INIT_META_READING 1
#define INIT_META_READ_DONE 2 #define INIT_META_READ_DONE 2
#define INIT_META_WRITING 3
#define GET_SQE() \ #define GET_SQE() \
sqe = bs->get_sqe();\ sqe = bs->get_sqe();\
@@ -73,25 +72,19 @@ resume_1:
} }
if (is_zero((uint64_t*)bs->meta_superblock, bs->dsk.meta_block_size)) if (is_zero((uint64_t*)bs->meta_superblock, bs->dsk.meta_block_size))
{ {
{ assert(bs->dsk.meta_format == BLOCKSTORE_META_FORMAT_HEAP);
blockstore_meta_header_v3_t *hdr = (blockstore_meta_header_v3_t *)bs->meta_superblock; blockstore_meta_header_v3_t *hdr = (blockstore_meta_header_v3_t *)bs->meta_superblock;
hdr->zero = 0; hdr->zero = 0;
hdr->magic = BLOCKSTORE_META_MAGIC_V1; hdr->magic = BLOCKSTORE_META_MAGIC_V1;
hdr->version = bs->dsk.meta_format; hdr->version = bs->dsk.meta_format;
hdr->meta_block_size = bs->dsk.meta_block_size; hdr->meta_block_size = bs->dsk.meta_block_size;
hdr->data_block_size = bs->dsk.data_block_size; hdr->data_block_size = bs->dsk.data_block_size;
hdr->bitmap_granularity = bs->dsk.bitmap_granularity; hdr->bitmap_granularity = bs->dsk.bitmap_granularity;
if (bs->dsk.meta_format >= BLOCKSTORE_META_FORMAT_V2) hdr->completed_lsn = 0;
{ hdr->data_csum_type = bs->dsk.data_csum_type;
hdr->data_csum_type = bs->dsk.data_csum_type; hdr->csum_block_size = bs->dsk.csum_block_size;
hdr->csum_block_size = bs->dsk.csum_block_size; hdr->meta_area_size = bs->dsk.meta_area_size;
} hdr->set_crc32c();
if (bs->dsk.meta_format >= BLOCKSTORE_META_FORMAT_HEAP)
{
hdr->meta_area_size = bs->dsk.meta_area_size;
}
hdr->set_crc32c();
}
if (bs->readonly) if (bs->readonly)
{ {
printf("Skipping metadata initialization because blockstore is readonly\n"); printf("Skipping metadata initialization because blockstore is readonly\n");
@@ -99,21 +92,8 @@ resume_1:
else else
{ {
printf("Initializing metadata area\n"); printf("Initializing metadata area\n");
GET_SQE();
last_read_offset = 0;
data->iov = (struct iovec){ bs->meta_superblock, (size_t)bs->dsk.meta_block_size };
data->callback = [this](ring_data_t *data) { handle_event(data, -1, "write metadata header"); };
io_uring_prep_writev(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset);
bs->ringloop->submit();
submitted++;
resume_2:
if (submitted > 0)
{
wait_state = 2;
return 1;
}
zero_on_init = true;
} }
zero_on_init = true;
} }
else else
{ {
@@ -164,7 +144,7 @@ resume_1:
hdr->header_csum = csum; hdr->header_csum = csum;
} }
bs->heap->start_load(((blockstore_meta_header_v3_t *)bs->meta_superblock)->completed_lsn); bs->heap->start_load(((blockstore_meta_header_v3_t *)bs->meta_superblock)->completed_lsn);
if (bs->dsk.inmemory_journal) if (bs->dsk.inmemory_journal && !zero_on_init)
{ {
// Read buffer area // Read buffer area
printf("Reading buffered data\n"); printf("Reading buffered data\n");
@@ -195,7 +175,7 @@ resume_3:
next_offset = md_offset; next_offset = md_offset;
// Read the rest of the metadata // Read the rest of the metadata
resume_4: resume_4:
if (next_offset < bs->dsk.meta_area_size && submitted == 0) if (next_offset < bs->dsk.meta_area_size && submitted == 0 && (!zero_on_init || !bs->readonly))
{ {
// Submit one read // Submit one read
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
@@ -236,11 +216,14 @@ resume_4:
if (bufs[i].state == INIT_META_READ_DONE) if (bufs[i].state == INIT_META_READ_DONE)
{ {
// Handle result // Handle result
uint64_t loaded = 0; if (!zero_on_init)
int r = bs->heap->load_blocks(bufs[i].offset-bs->dsk.meta_block_size, bufs[i].size, bufs[i].buf, bs->skip_corrupted_meta_entries, loaded); {
if (r != 0) uint64_t loaded = 0;
exit(1); int r = bs->heap->load_blocks(bufs[i].offset-bs->dsk.meta_block_size, bufs[i].size, bufs[i].buf, bs->skip_corrupted_meta_entries, loaded);
entries_loaded += loaded; if (r != 0)
exit(1);
entries_loaded += loaded;
}
bufs[i].state = 0; bufs[i].state = 0;
bs->ringloop->wakeup(); bs->ringloop->wakeup();
} }
@@ -250,7 +233,7 @@ resume_4:
wait_state = 4; wait_state = 4;
return 1; return 1;
} }
// metadata read finished // metadata read/clear finished
bs->heap->finish_load(); bs->heap->finish_load();
printf("Metadata entries loaded: %ju, rechecking unfinished writes and garbage entries\n", entries_loaded); printf("Metadata entries loaded: %ju, rechecking unfinished writes and garbage entries\n", entries_loaded);
// asynchronous recheck // asynchronous recheck
@@ -333,6 +316,7 @@ resume_9:
} }
free(metadata_buffer); free(metadata_buffer);
metadata_buffer = NULL; metadata_buffer = NULL;
do_fsync:
if (!bs->dsk.disable_meta_fsync && !bs->readonly) if (!bs->dsk.disable_meta_fsync && !bs->readonly)
{ {
GET_SQE(); GET_SQE();
@@ -349,6 +333,27 @@ resume_9:
return 1; return 1;
} }
} }
if (zero_on_init && !header_written && !bs->readonly)
{
GET_SQE();
header_written = true;
last_read_offset = 0;
data->iov = (struct iovec){ bs->meta_superblock, (size_t)bs->dsk.meta_block_size };
data->callback = [this](ring_data_t *data) { handle_event(data, -1, "write metadata header"); };
io_uring_prep_writev(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset);
bs->ringloop->submit();
submitted++;
resume_2:
if (submitted > 0)
{
wait_state = 2;
return 1;
}
if (!bs->dsk.disable_meta_fsync)
{
goto do_fsync;
}
}
printf("Loading finished. Data used: %ju / %ju bytes (%s / %s)\n", printf("Loading finished. Data used: %ju / %ju bytes (%s / %s)\n",
bs->heap->get_data_used_space(), bs->dsk.block_count * bs->dsk.data_block_size, bs->heap->get_data_used_space(), bs->dsk.block_count * bs->dsk.data_block_size,
format_size(bs->heap->get_data_used_space()).c_str(), format_size(bs->heap->get_data_used_space()).c_str(),
+1
View File
@@ -17,6 +17,7 @@ class blockstore_init_meta
int wait_state = 0; int wait_state = 0;
int wait_count = 0; int wait_count = 0;
bool zero_on_init = false; bool zero_on_init = false;
bool header_written = false;
void *metadata_buffer = NULL; void *metadata_buffer = NULL;
blockstore_init_meta_buf bufs[2] = {}; blockstore_init_meta_buf bufs[2] = {};
int submitted = 0; int submitted = 0;