Initialize parity split sizes before pre-resize state checkpoint

This commit is contained in:
Andrea Mazzoleni
2026-08-31 10:39:17 +02:00
parent 2774a6488f
commit 80b58e66d5
6 changed files with 130 additions and 0 deletions
+55
View File
@@ -185,6 +185,10 @@ EXTRA_DIST = \
test/test-par4.conf \
test/test-par5.conf \
test/test-par6.conf \
test/test-realloc-level1.conf \
test/test-realloc-level2.conf \
test/test-realloc-split1.conf \
test/test-realloc-split2.conf \
test/test-par6-hole.conf \
test/test-par6-noaccess.conf \
test/test-par6-rename.conf \
@@ -329,6 +333,10 @@ PARZ = $(srcdir)/test/test-parz.conf
PAR4 = $(srcdir)/test/test-par4.conf
PAR5 = $(srcdir)/test/test-par5.conf
PAR6 = $(srcdir)/test/test-par6.conf
REALLOC_LEVEL1 = $(srcdir)/test/test-realloc-level1.conf
REALLOC_LEVEL2 = $(srcdir)/test/test-realloc-level2.conf
REALLOC_SPLIT1 = $(srcdir)/test/test-realloc-split1.conf
REALLOC_SPLIT2 = $(srcdir)/test/test-realloc-split2.conf
SNAP = $(srcdir)/test/test-snap.conf
MSG = @echo =====
SNAPRAID = ./checker$(EXEEXT)
@@ -1282,6 +1290,53 @@ endif # !HAVE_MEMORY_CHECKER
$(MSG) Sync after all the fixes
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(CONF) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(CONF) check
rm -rf bench/realloc-level
mkdir -p bench/realloc-level/disk1
mkdir -p bench/realloc-level/disk2
mkdir -p bench/realloc-level/disk3
mkdir -p bench/realloc-level/disk4
mkdir -p bench/realloc-level/disk5
mkdir -p bench/realloc-level/disk6
dd bs=1024 count=2048 if=/dev/urandom of=bench/realloc-level/disk1/data
#### NEW PARITY CONFIGURATION CRASH TESTS ####
$(MSG) Test interrupted force-realloc after adding a parity level
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL1) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) -R --test-kill-after-resize sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) locate > /dev/null
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_LEVEL2) check
rm -rf bench/realloc-split
mkdir -p bench/realloc-split/disk1
mkdir -p bench/realloc-split/disk2
mkdir -p bench/realloc-split/disk3
mkdir -p bench/realloc-split/disk4
mkdir -p bench/realloc-split/disk5
mkdir -p bench/realloc-split/disk6
dd bs=1024 count=2048 if=/dev/urandom of=bench/realloc-split/disk1/data1
$(MSG) Test interrupted force-realloc after adding a parity split
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT1) sync
dd bs=1024 count=2048 if=/dev/urandom of=bench/realloc-split/disk1/data2
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT2) -R --test-kill-after-resize sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT2) locate > /dev/null
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT2) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT2) check
$(MSG) Test interrupted normal shrink after adding a parity split
rm -rf bench/realloc-split
mkdir -p bench/realloc-split/disk1
mkdir -p bench/realloc-split/disk2
mkdir -p bench/realloc-split/disk3
mkdir -p bench/realloc-split/disk4
mkdir -p bench/realloc-split/disk5
mkdir -p bench/realloc-split/disk6
dd bs=1024 count=2048 if=/dev/urandom of=bench/realloc-split/disk1/data
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT1) sync
dd bs=1024 count=1024 if=/dev/urandom of=bench/realloc-split/disk1/NORMAL_SPLIT_SHRINK
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT1) sync
rm bench/realloc-split/disk1/NORMAL_SPLIT_SHRINK
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT2) --test-kill-after-resize sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT2) locate > /dev/null
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT2) sync
$(TESTENV) $(SNAPRAID) $(CHECKFLAGS) -c $(REALLOC_SPLIT2) check
#### FORCE-REALLOC CRASH TESTS ####
$(MSG) Test interrupted force-realloc post-resize crash
dd bs=1024 count=1024 if=/dev/urandom of=bench/disk1/REALLOC_CRASH1
+34
View File
@@ -1861,6 +1861,37 @@ static void state_sync_mark_rebuild(struct snapraid_state* state)
state->need_write = 1;
}
/*
* Initialize persistent parity split sizes resolved while opening parity.
*
* parity_create() resolves PARITY_SIZE_INVALID in the parity handles using
* the current physical file size, but intentionally doesn't modify the
* persistent parity state.
*
* Before writing a pre-resize recovery checkpoint, copy only these resolved
* initial sizes into the persistent state. Existing valid sizes must be
* preserved because they describe the previously persisted logical split
* layout.
*/
static void state_sync_parity_size(struct snapraid_state* state, struct snapraid_parity_handle* parity_handle)
{
unsigned l;
unsigned s;
int modified = 0;
for (l = 0; l < state->level; ++l) {
for (s = 0; s < state->parity[l].split_mac; ++s) {
if (state->parity[l].split_map[s].size == PARITY_SIZE_INVALID) {
state->parity[l].split_map[s].size = parity_handle[l].split_map[s].size;
modified = 1;
}
}
}
if (modified)
state->need_write = 1;
}
int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount)
{
block_off_t blockmax;
@@ -2024,6 +2055,9 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
if (state->opt.force_full)
state_sync_mark_rebuild(state);
if (state->opt.force_full || state->opt.force_realloc || parity_shrink)
state_sync_parity_size(state, parity_handle);
if ((state->opt.force_full
|| state->opt.force_realloc
|| parity_shrink)
+10
View File
@@ -0,0 +1,10 @@
# Test configuration for adding a parity level during force-realloc
blocksize 1
parity bench/realloc-level/parity
content bench/realloc-level/content
disk disk1 bench/realloc-level/disk1/
disk disk2 bench/realloc-level/disk2/
disk disk3 bench/realloc-level/disk3/
disk disk4 bench/realloc-level/disk4/
disk disk5 bench/realloc-level/disk5/
disk disk6 bench/realloc-level/disk6/
+11
View File
@@ -0,0 +1,11 @@
# Test configuration for adding a parity level during force-realloc
blocksize 1
parity bench/realloc-level/parity
2-parity bench/realloc-level/2-parity
content bench/realloc-level/content
disk disk1 bench/realloc-level/disk1/
disk disk2 bench/realloc-level/disk2/
disk disk3 bench/realloc-level/disk3/
disk disk4 bench/realloc-level/disk4/
disk disk5 bench/realloc-level/disk5/
disk disk6 bench/realloc-level/disk6/
+10
View File
@@ -0,0 +1,10 @@
# Test configuration for adding a parity split during force-realloc
blocksize 1
parity bench/realloc-split/parity.0
content bench/realloc-split/content
disk disk1 bench/realloc-split/disk1/
disk disk2 bench/realloc-split/disk2/
disk disk3 bench/realloc-split/disk3/
disk disk4 bench/realloc-split/disk4/
disk disk5 bench/realloc-split/disk5/
disk disk6 bench/realloc-split/disk6/
+10
View File
@@ -0,0 +1,10 @@
# Test configuration for adding a parity split during force-realloc
blocksize 1
parity bench/realloc-split/parity.0,bench/realloc-split/parity.1
content bench/realloc-split/content
disk disk1 bench/realloc-split/disk1/
disk disk2 bench/realloc-split/disk2/
disk disk3 bench/realloc-split/disk3/
disk disk4 bench/realloc-split/disk4/
disk disk5 bench/realloc-split/disk5/
disk disk6 bench/realloc-split/disk6/