diff --git a/cmdline/check.c b/cmdline/check.c index b65849e5..99c7fc96 100644 --- a/cmdline/check.c +++ b/cmdline/check.c @@ -2042,14 +2042,26 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b /* try to close only if opened */ for (l = 0; l < state->level; ++l) { if (parity_ptr[l]) { + /* if fixing and not excluded, truncate parity not valid */ + if (fix && !state->parity[l].is_excluded_by_filter) { + ret = parity_truncate(parity_ptr[l]); + if (ret == -1) { + /* LCOV_EXCL_START */ + log_fatal("DANGER! Unexpected truncate error in %s disk.\n", lev_name(l)); + ++error; + /* continue, as we are already exiting */ + /* LCOV_EXCL_STOP */ + } + } + ret = parity_close(parity_ptr[l]); - /* LCOV_EXCL_START */ if (ret == -1) { + /* LCOV_EXCL_START */ log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l)); ++error; /* continue, as we are already exiting */ + /* LCOV_EXCL_STOP */ } - /* LCOV_EXCL_STOP */ } } diff --git a/cmdline/parity.c b/cmdline/parity.c index f585ba9b..2eb10665 100644 --- a/cmdline/parity.c +++ b/cmdline/parity.c @@ -184,7 +184,6 @@ int parity_create(struct snapraid_parity_handle* handle, const struct snapraid_p handle->level = level; handle->split_mac = 0; - handle->has_write_access = 0; for (s = 0; s < parity->split_mac; ++s) { struct snapraid_split_handle* split = &handle->split_map[s]; @@ -667,7 +666,6 @@ int parity_open(struct snapraid_parity_handle* handle, const struct snapraid_par handle->level = level; handle->split_mac = 0; - handle->has_write_access = 0; /* mask of bits used by the block size */ block_mask = ((data_off_t)block_size) - 1; @@ -773,7 +771,7 @@ int parity_sync(struct snapraid_parity_handle* handle) return 0; } -int parity_close(struct snapraid_parity_handle* handle) +int parity_truncate(struct snapraid_parity_handle* handle) { unsigned s; int f_ret = 0; @@ -782,18 +780,29 @@ int parity_close(struct snapraid_parity_handle* handle) struct snapraid_split_handle* split = &handle->split_map[s]; int ret; - if (handle->has_write_access) { - /* truncate any data that we know it's not valid */ - ret = ftruncate(split->f, split->valid_size); - if (ret != 0) { - /* LCOV_EXCL_START */ - log_fatal("Error truncating the parity file '%s' to size %" PRIu64 ". %s.\n", split->path, split->valid_size, strerror(errno)); - f_ret = -1; - /* LCOV_EXCL_STOP */ + /* truncate any data that we know it's not valid */ + ret = ftruncate(split->f, split->valid_size); + if (ret != 0) { + /* LCOV_EXCL_START */ + log_fatal("Error truncating the parity file '%s' to size %" PRIu64 ". %s.\n", split->path, split->valid_size, strerror(errno)); + f_ret = -1; + /* LCOV_EXCL_STOP */ - /* continue to close the others */ - } + /* continue to truncate the others */ } + } + + return f_ret; +} + +int parity_close(struct snapraid_parity_handle* handle) +{ + unsigned s; + int f_ret = 0; + + for (s = 0; s < handle->split_mac; ++s) { + struct snapraid_split_handle* split = &handle->split_map[s]; + int ret; ret = close(split->f); if (ret != 0) { diff --git a/cmdline/parity.h b/cmdline/parity.h index 3e52d3c1..3380eb7d 100644 --- a/cmdline/parity.h +++ b/cmdline/parity.h @@ -38,8 +38,11 @@ struct snapraid_split_handle { /** * Valid size of the parity split. - * This is the size effectively written, and not the reult of a chsize operation. + * This is the size effectively written, and not the result of a chsize operation. * It's used to make read operations failing if read over that size. + * + * Parity is also truncated to that size when fixing it, in case of a Break (Ctrl+C) + * of the program. */ data_off_t valid_size; @@ -54,7 +57,6 @@ struct snapraid_parity_handle { struct snapraid_split_handle split_map[SPLIT_MAX]; unsigned split_mac; /**< Number of parity splits. */ unsigned level; /**< Level of the parity. */ - int has_write_access; /**< If the parity is open for writing. */ }; /** @@ -121,6 +123,11 @@ int parity_open(struct snapraid_parity_handle* handle, const struct snapraid_par */ int parity_sync(struct snapraid_parity_handle* handle); +/** + * Truncate the parity file to the valid size. + */ +int parity_truncate(struct snapraid_parity_handle* handle); + /** * Close the parity file. */