Make snapraid_io track started state and defer async I/O after initial thermal control

This commit is contained in:
Andrea Mazzoleni 2026-09-07 10:15:13 +02:00
parent 595461f725
commit 74647cda14
6 changed files with 39 additions and 16 deletions

View file

@ -185,15 +185,15 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
countpos = 0;
blockcur = blockstart;
/* start all the worker threads */
io_start(&io, blockstart, blockmax, 0);
int alert = state_progress_begin(state, blockstart, blockmax, countmax);
if (alert > 0)
goto end;
if (alert < 0)
goto bail;
/* start all the worker threads */
io_start(&io, blockstart, blockmax, 0);
while (1) {
void** buffer;

View file

@ -295,6 +295,7 @@ static void io_start_mono(struct snapraid_io* io,
{
unsigned i;
io->started = 1;
io->block_start = blockstart;
io->block_max = blockmax;
io->block_enabled = block_enabled;
@ -307,7 +308,10 @@ static void io_start_mono(struct snapraid_io* io,
static void io_stop_mono(struct snapraid_io* io)
{
(void)io;
if (!io->started)
return;
io->started = 0;
}
/*****************************************************************************/
@ -579,6 +583,11 @@ static void io_flush_thread(struct snapraid_io* io, int* writer_error)
{
unsigned i;
if (!io->started) {
io_writer_error_get(io, writer_error);
return;
}
while (1) {
int all_done = 1;
@ -628,6 +637,9 @@ static void io_quiesce_thread(struct snapraid_io* io)
{
unsigned i;
if (!io->started)
return;
while (1) {
int all_done = 1;
@ -923,6 +935,7 @@ static void io_start_thread(struct snapraid_io* io,
{
unsigned i;
io->started = 1;
io->block_start = blockstart;
io->block_max = blockmax;
io->block_enabled = block_enabled;
@ -976,6 +989,11 @@ static void io_stop_thread(struct snapraid_io* io)
{
unsigned i;
if (!io->started)
return;
io->started = 0;
thread_mutex_lock(&io->io_mutex);
/* mark that we are stopping */
@ -1033,6 +1051,9 @@ void io_init(struct snapraid_io* io, struct snapraid_state* state,
io_op_t parity_op_default = IO_OP_NONE;
io->state = state;
io->started = 0;
for (i = 0; i < IO_WRITER_ERROR_MAX; ++i)
io->writer_error[i] = 0;
assert(buffer_max >= handle_max + parity_handle_max);

View file

@ -320,6 +320,11 @@ struct snapraid_io {
*/
int done;
/**
* If worker threads have been started.
*/
int started;
/**
* The worker task index currently used by the operation in
* progress. It's the position in all the reader task_map[].

View file

@ -529,15 +529,15 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
msg_progress("Scrubbing...\n");
/* start all the worker threads */
io_start(&io, blockstart, blockmax, block_enabled);
int alert = state_progress_begin(state, blockstart, blockmax, countmax);
if (alert > 0)
goto end;
if (alert < 0)
goto bail;
/* start all the worker threads */
io_start(&io, blockstart, blockmax, block_enabled);
while (1) {
unsigned char* buffer_recov[LEV_MAX];
snapraid_info info;

View file

@ -1026,15 +1026,15 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
msg_progress("Syncing...\n");
/* start all the worker threads */
io_start(&io, blockstart, blockmax, block_enabled);
int alert = state_progress_begin(state, blockstart, blockmax, countmax);
if (alert > 0)
goto end;
if (alert < 0)
goto bail_abort;
/* start all the worker threads */
io_start(&io, blockstart, blockmax, block_enabled);
while (1) {
unsigned failed_count;
int error_on_this_block;

View file

@ -345,7 +345,7 @@ void state_thermal_cooldown(struct snapraid_state* state)
int sleep_time = cooldown_time;
log_tag("thermal:spindown\n");
/*
* Power management is best effort.
*
@ -417,11 +417,8 @@ int state_thermal_begin(struct snapraid_state* state, time_t now)
}
if (state_thermal_alarm(state)) {
/* LCOV_EXCL_START */
log_fatal(EENVIRONMENT, "DANGER! Hard disk temperature of %d degrees is already outside the operating range. Unable to proceed!\n", state->thermal_highest_temperature);
log_flush();
return 0;
/* LCOV_EXCL_STOP */
msg_progress("Hard disk temperature of %d degrees is already outside the operating range. Cooling down before starting...\n", state->thermal_highest_temperature);
state_thermal_cooldown(state);
}
return 1;