mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-25 18:40:19 -04:00
Restore error reporting for parity write
This commit is contained in:
parent
fa635f72b8
commit
4191989fa7
3 changed files with 67 additions and 6 deletions
31
cmdline/io.c
31
cmdline/io.c
|
|
@ -274,14 +274,20 @@ static struct snapraid_task* io_reader_step(struct snapraid_worker* worker)
|
|||
*
|
||||
* This is the synchronization point for workers with the io.
|
||||
*/
|
||||
static struct snapraid_task* io_writer_step(struct snapraid_worker* worker)
|
||||
static struct snapraid_task* io_writer_step(struct snapraid_worker* worker, int state)
|
||||
{
|
||||
struct snapraid_io* io = worker->io;
|
||||
struct snapraid_task* task = 0;
|
||||
int error_index;
|
||||
|
||||
/* the synchronization is protected by the io mutex */
|
||||
pthread_mutex_lock(&io->mutex);
|
||||
|
||||
/* counts the number of errors in the global state */
|
||||
error_index = state - IO_WRITER_ERROR_BASE;
|
||||
if (error_index >= 0 && error_index < IO_WRITER_ERROR_MAX)
|
||||
++io->writer_error[error_index];
|
||||
|
||||
while (1) {
|
||||
unsigned index;
|
||||
|
||||
|
|
@ -359,7 +365,7 @@ block_off_t io_read_next(struct snapraid_io* io, void*** buffer)
|
|||
return blockcur_caller;
|
||||
}
|
||||
|
||||
void io_write_next(struct snapraid_io* io, unsigned blockcur, int skip)
|
||||
void io_write_next(struct snapraid_io* io, unsigned blockcur, int skip, int* writer_error)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
|
|
@ -373,6 +379,12 @@ void io_write_next(struct snapraid_io* io, unsigned blockcur, int skip)
|
|||
/* the synchronization is protected by the io mutex */
|
||||
pthread_mutex_lock(&io->mutex);
|
||||
|
||||
/* report errors */
|
||||
for (i = 0; i < IO_WRITER_ERROR_MAX; ++i) {
|
||||
writer_error[i] = io->writer_error[i];
|
||||
io->writer_error[i] = 0;
|
||||
}
|
||||
|
||||
if (skip) {
|
||||
/* skip the next write */
|
||||
io_writer_sched_empty(io, io->writer_index, blockcur);
|
||||
|
|
@ -554,28 +566,35 @@ static void* io_reader_thread(void* arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void* io_writer_thread(void* arg)
|
||||
{
|
||||
struct snapraid_worker* worker = arg;
|
||||
int latest_state = TASK_STATE_DONE;
|
||||
|
||||
while (1) {
|
||||
struct snapraid_task* task;
|
||||
|
||||
/* get the new task */
|
||||
task = io_writer_step(worker);
|
||||
task = io_writer_step(worker, latest_state);
|
||||
|
||||
/* if no task, it means to exit */
|
||||
if (!task)
|
||||
break;
|
||||
|
||||
/* nothing more to do */
|
||||
if (task->state == TASK_STATE_EMPTY)
|
||||
if (task->state == TASK_STATE_EMPTY) {
|
||||
latest_state = TASK_STATE_DONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(task->state == TASK_STATE_READY);
|
||||
|
||||
/* work on the assigned task */
|
||||
worker->func(worker, task);
|
||||
|
||||
/* save the resulting state */
|
||||
latest_state = task->state;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -597,6 +616,10 @@ void io_start(struct snapraid_io* io,
|
|||
io->reader_index = IO_MAX - 1;
|
||||
io->writer_index = 0;
|
||||
|
||||
/* clear writer errors */
|
||||
for (i = 0; i < IO_WRITER_ERROR_MAX; ++i)
|
||||
io->writer_error[i] = 0;
|
||||
|
||||
/* setup the initial read pending tasks, except the latest one, */
|
||||
/* the latest will be initialized at the fist io_read_next() call */
|
||||
for (i = 0; i < IO_MAX - 1; ++i) {
|
||||
|
|
|
|||
14
cmdline/io.h
14
cmdline/io.h
|
|
@ -120,6 +120,12 @@ struct snapraid_worker {
|
|||
unsigned buffer_skew;
|
||||
};
|
||||
|
||||
/**
|
||||
* Number of error kind for writers.
|
||||
*/
|
||||
#define IO_WRITER_ERROR_BASE TASK_STATE_IOERROR_CONTINUE
|
||||
#define IO_WRITER_ERROR_MAX (-IO_WRITER_ERROR_BASE)
|
||||
|
||||
/**
|
||||
* Reader.
|
||||
*
|
||||
|
|
@ -258,6 +264,11 @@ struct snapraid_io {
|
|||
* it's incremented, and a write_sched() signal is sent.
|
||||
*/
|
||||
unsigned writer_index;
|
||||
|
||||
/**
|
||||
* Counts the error happening in the writers.
|
||||
*/
|
||||
int writer_error[IO_WRITER_ERROR_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -343,7 +354,8 @@ void io_parity_write(struct snapraid_io* io, unsigned* levcur);
|
|||
* \param io InputOutput context.
|
||||
* \param blockcur The parity position to write.
|
||||
* \param skip Skip the writes, in case parity doesn't need to be updated.
|
||||
* \param writer_error Return the number of errors. Vector of IO_WRITER_ERROR_MAX elements.
|
||||
*/
|
||||
void io_write_next(struct snapraid_io* io, unsigned blockcur, int skip);
|
||||
void io_write_next(struct snapraid_io* io, unsigned blockcur, int skip, int* writer_error);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -747,6 +747,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
snapraid_info info;
|
||||
int rehash;
|
||||
void** buffer;
|
||||
int writer_error[IO_WRITER_ERROR_MAX];
|
||||
|
||||
/* go to the next block */
|
||||
blockcur = io_read_next(&io, &buffer);
|
||||
|
|
@ -1193,7 +1194,32 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
}
|
||||
|
||||
/* write finished */
|
||||
io_write_next(&io, blockcur, !parity_going_to_be_updated);
|
||||
io_write_next(&io, blockcur, !parity_going_to_be_updated, writer_error);
|
||||
|
||||
/* handle errors reported */
|
||||
for (j = 0; j < IO_WRITER_ERROR_MAX; ++j) {
|
||||
if (writer_error[j]) {
|
||||
switch (j + IO_WRITER_ERROR_BASE) {
|
||||
case TASK_STATE_IOERROR_CONTINUE :
|
||||
++io_error;
|
||||
if (io_error >= state->opt.io_error_limit) {
|
||||
log_fatal("DANGER! Unexpected input/output write error in a parity disk, it isn't possible to sync.\n");
|
||||
log_fatal("Stopping at block %u\n", blockcur);
|
||||
goto bail;
|
||||
}
|
||||
break;
|
||||
case TASK_STATE_ERROR_CONTINUE :
|
||||
++error;
|
||||
break;
|
||||
case TASK_STATE_IOERROR :
|
||||
++io_error;
|
||||
goto bail;
|
||||
case TASK_STATE_ERROR :
|
||||
++error;
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* mark the state as needing write */
|
||||
state->need_write = 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue