修复IWDG超时未配置与dhara resume回滚:看门狗误复位与复位后写入全部丢失,台架全量自检PASS
This commit is contained in:
+31
-2
@@ -553,7 +553,7 @@ int dhara_journal_resume(struct dhara_journal *j, dhara_error_t *err)
|
||||
{
|
||||
dhara_block_t first, last, last_any;
|
||||
dhara_page_t last_group;
|
||||
uint8_t first_epoch;
|
||||
uint8_t first_epoch, last_epoch;
|
||||
|
||||
/* Find the first checkpoint-containing block */
|
||||
if (find_checkblock(j, 0, &first, err) < 0) {
|
||||
@@ -572,13 +572,42 @@ int dhara_journal_resume(struct dhara_journal *j, dhara_error_t *err)
|
||||
* lifetime on the next resume. Measured 2026-09-20: this made a
|
||||
* self-heal volume reformat vanish on every reset (infinite
|
||||
* reformat loop, no data persistence).
|
||||
*
|
||||
* 2026-10-02 (local fix): the previous anchor picked the checkpoint
|
||||
* at the HIGHEST block address. That is only the newest when the
|
||||
* ring has not wrapped. The ring writes sequentially and bumps the
|
||||
* epoch at each wrap, so once it HAS wrapped the newest checkpoints
|
||||
* live at the LOWEST addresses and the highest-address ones are
|
||||
* leftovers from the previous pass (one epoch older). Anchoring on
|
||||
* those made every resume roll the journal back to the pre-wrap
|
||||
* state: measured on the bench, head went 96 -> 130752 and tail
|
||||
* 115143 -> 115068 on every reset, so NOTHING written after the
|
||||
* wrap (log records, config saves, FTP uploads) ever survived a
|
||||
* reset.
|
||||
*
|
||||
* Both cases are decided by comparing the two candidate epochs,
|
||||
* which are always adjacent because the ring wraps at most once
|
||||
* per pass:
|
||||
* - equal -> no wrap between them; either is fine.
|
||||
* - eFirst == eLast + 1 -> the ring wrapped; the low-address
|
||||
* checkpoints are the newest.
|
||||
* - otherwise -> the low-address checkpoints are stale
|
||||
* leftovers; the high ones are newest.
|
||||
*/
|
||||
last_any = find_last_checkblock_any(j, first);
|
||||
if (read_checkpage(j, last_any, err) < 0) {
|
||||
reset_journal(j);
|
||||
return -1;
|
||||
}
|
||||
j->epoch = hdr_get_epoch(j->page_buf);
|
||||
last_epoch = hdr_get_epoch(j->page_buf);
|
||||
|
||||
if (first_epoch == last_epoch) {
|
||||
j->epoch = first_epoch;
|
||||
} else if ((uint8_t)(first_epoch - last_epoch) == 1u) {
|
||||
j->epoch = first_epoch;
|
||||
} else {
|
||||
j->epoch = last_epoch;
|
||||
}
|
||||
|
||||
if (first_epoch == j->epoch) {
|
||||
/* Single-epoch ring: original code path, unchanged. */
|
||||
|
||||
Reference in New Issue
Block a user