Split the parity close and truncate operations

To avoid any possible conflicts.
This commit is contained in:
Andrea Mazzoleni 2019-05-21 22:33:24 +02:00
parent 78681715c6
commit 9a21995a61
3 changed files with 45 additions and 17 deletions

View file

@ -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 */
}
}

View file

@ -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) {

View file

@ -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.
*/