diff --git a/cmdline/check.c b/cmdline/check.c index 4e63a870..07019f15 100644 --- a/cmdline/check.c +++ b/cmdline/check.c @@ -1815,7 +1815,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b /* if it fails, we cannot continue */ for (l = 0; l < state->level; ++l) { parity_ptr[l] = &parity[l]; - ret = parity_create(parity_ptr[l], state->parity_path[l], &out_size, state->file_mode); + ret = parity_create(parity_ptr[l], state->parity[l].path, &out_size, state->file_mode); if (ret == -1) { /* LCOV_EXCL_START */ fprintf(stderr, "WARNING! Without an accessible %s file, it isn't possible to fix any error.\n", lev_name(l)); @@ -1836,7 +1836,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b /* it may fail if the file doesn't exist, in this case we continue to check the files */ for (l = 0; l < state->level; ++l) { parity_ptr[l] = &parity[l]; - ret = parity_open(parity_ptr[l], state->parity_path[l], state->file_mode); + ret = parity_open(parity_ptr[l], state->parity[l].path, state->file_mode); if (ret == -1) { printf("No accessible %s file, only files will be checked.\n", lev_name(l)); /* continue anyway */ diff --git a/cmdline/dry.c b/cmdline/dry.c index 6bb2636a..8b3b612e 100644 --- a/cmdline/dry.c +++ b/cmdline/dry.c @@ -205,7 +205,7 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t /* it may fail if the file doesn't exist, in this case we continue to dry the files */ for (l = 0; l < state->level; ++l) { parity_ptr[l] = &parity[l]; - ret = parity_open(parity_ptr[l], state->parity_path[l], state->file_mode); + ret = parity_open(parity_ptr[l], state->parity[l].path, state->file_mode); if (ret == -1) { printf("No accessible %s file.\n", lev_name(l)); /* continue anyway */ diff --git a/cmdline/elem.h b/cmdline/elem.h index 175377c7..1cae074f 100644 --- a/cmdline/elem.h +++ b/cmdline/elem.h @@ -371,6 +371,14 @@ struct snapraid_map { tommy_node node; }; +/** + * Parity. + */ +struct snapraid_parity { + char path[PATH_MAX]; /**< Path of the parity file. */ + uint64_t device; /**< Device identifier of the parity. */ +}; + /** * Info. */ diff --git a/cmdline/scrub.c b/cmdline/scrub.c index 14c4a404..ed4c242f 100644 --- a/cmdline/scrub.c +++ b/cmdline/scrub.c @@ -618,7 +618,7 @@ int state_scrub(struct snapraid_state* state, int percentage, int olderthan) /* open the file for reading */ for (l = 0; l < state->level; ++l) { parity_ptr[l] = &parity[l]; - ret = parity_open(parity_ptr[l], state->parity_path[l], state->file_mode); + ret = parity_open(parity_ptr[l], state->parity[l].path, state->file_mode); if (ret == -1) { /* LCOV_EXCL_START */ fprintf(stderr, "WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l)); diff --git a/cmdline/state.c b/cmdline/state.c index 6dad39ea..8df5cb87 100644 --- a/cmdline/state.c +++ b/cmdline/state.c @@ -84,8 +84,8 @@ void state_init(struct snapraid_state* state) state->raid_mode = RAID_MODE_CAUCHY; state->file_mode = MODE_SEQUENTIAL; for (l = 0; l < LEV_MAX; ++l) { - state->parity_path[l][0] = 0; - state->parity_device[l] = 0; + state->parity[l].path[0] = 0; + state->parity[l].device = 0; state->tick_parity[l] = 0; } state->tick_io = 0; @@ -144,7 +144,7 @@ static void state_config_check(struct snapraid_state* state, const char* path, t } for (l = 0; l < state->level; ++l) { - if (state->parity_path[l][0] == 0) { + if (state->parity[l].path[0] == 0) { /* LCOV_EXCL_START */ fprintf(stderr, "No '%s' specification in '%s'\n", lev_config_name(l), path); exit(EXIT_FAILURE); @@ -164,7 +164,7 @@ static void state_config_check(struct snapraid_state* state, const char* path, t struct snapraid_content* content = i->data; for (l = 0; l < state->level; ++l) { - if (pathcmp(state->parity_path[l], content->content) == 0) { + if (pathcmp(state->parity[l].path, content->content) == 0) { /* LCOV_EXCL_START */ fprintf(stderr, "Same path used for '%s' and 'content' as '%s'\n", lev_config_name(l), content->content); exit(EXIT_FAILURE); @@ -213,9 +213,9 @@ static void state_config_check(struct snapraid_state* state, const char* path, t } for (l = 0; l < state->level; ++l) { - if (disk->device == state->parity_device[l]) { + if (disk->device == state->parity[l].device) { /* LCOV_EXCL_START */ - fprintf(stderr, "Disk '%s' and %s '%s' are on the same device.\n", disk->dir, lev_name(l), state->parity_path[l]); + fprintf(stderr, "Disk '%s' and %s '%s' are on the same device.\n", disk->dir, lev_name(l), state->parity[l].path); #ifdef _WIN32 fprintf(stderr, "Both have the serial number '%" PRIx64 "'.\n", disk->device); fprintf(stderr, "Try using the 'VolumeID' tool by 'Mark Russinovich'\n"); @@ -241,9 +241,9 @@ static void state_config_check(struct snapraid_state* state, const char* path, t #ifdef _WIN32 for (l = 0; l < state->level; ++l) { - if (state->parity_device[l] == 0) { + if (state->parity[l].device == 0) { /* LCOV_EXCL_START */ - fprintf(stderr, "Disk '%s' has a zero serial number.\n", state->parity_path[l]); + fprintf(stderr, "Disk '%s' has a zero serial number.\n", state->parity[l].path); fprintf(stderr, "This is not necessarely wrong, but for using SnapRAID\n"); fprintf(stderr, "it's better to change the serial number of the disk.\n"); fprintf(stderr, "Try using the 'VolumeID' tool by 'Mark Russinovich'.\n"); @@ -266,11 +266,11 @@ static void state_config_check(struct snapraid_state* state, const char* path, t for (l = 0; l < state->level; ++l) { unsigned j; for (j = l + 1; j < state->level; ++j) { - if (state->parity_device[l] == state->parity_device[j]) { + if (state->parity[l].device == state->parity[j].device) { /* LCOV_EXCL_START */ - fprintf(stderr, "Parity '%s' and '%s' are on the same device.\n", state->parity_path[l], state->parity_path[j]); + fprintf(stderr, "Parity '%s' and '%s' are on the same device.\n", state->parity[l].path, state->parity[j].path); #ifdef _WIN32 - fprintf(stderr, "Both have the serial number '%" PRIx64 "'.\n", state->parity_device[l]); + fprintf(stderr, "Both have the serial number '%" PRIx64 "'.\n", state->parity[l].device); fprintf(stderr, "Try using the 'VolumeID' tool by 'Mark Russinovich'\n"); fprintf(stderr, "to change one of the disk serial.\n"); #endif @@ -281,9 +281,9 @@ static void state_config_check(struct snapraid_state* state, const char* path, t } for (l = 0; l < state->level; ++l) { - if (state->pool[0] != 0 && state->pool_device == state->parity_device[l]) { + if (state->pool[0] != 0 && state->pool_device == state->parity[l].device) { /* LCOV_EXCL_START */ - fprintf(stderr, "Pool '%s' and parity '%s' are on the same device.\n", state->pool, state->parity_path[l]); + fprintf(stderr, "Pool '%s' and parity '%s' are on the same device.\n", state->pool, state->parity[l].path); #ifdef _WIN32 fprintf(stderr, "Both have the serial number '%" PRIx64 "'.\n", state->pool_device); fprintf(stderr, "Try using the 'VolumeID' tool by 'Mark Russinovich'\n"); @@ -487,7 +487,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co /* LCOV_EXCL_STOP */ } - if (*state->parity_path[level]) { + if (*state->parity[level].path) { /* LCOV_EXCL_START */ fprintf(stderr, "Multiple '%s' specification in '%s' at line %u\n", tag, path, line); exit(EXIT_FAILURE); @@ -509,7 +509,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co /* LCOV_EXCL_STOP */ } - pathimport(state->parity_path[level], sizeof(state->parity_path[level]), buffer); + pathimport(state->parity[level].path, sizeof(state->parity[level].path), buffer); if (!state->opt.skip_parity_access) { struct stat st; @@ -528,10 +528,10 @@ void state_config(struct snapraid_state* state, const char* path, const char* co /* LCOV_EXCL_STOP */ } - state->parity_device[level] = st.st_dev; + state->parity[level].device = st.st_dev; } else { /* if parity is skipped, uses a fake device */ - state->parity_device[level] = -1LL - level; + state->parity[level].device = -1LL - level; } /* adjust the level */ @@ -890,7 +890,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co fprintf(stdlog, "mode:%s\n", lev_raid_name(state->raid_mode, state->level)); for (l = 0; l < state->level; ++l) - fprintf(stdlog, "%s:%s\n", lev_config_name(l), state->parity_path[l]); + fprintf(stdlog, "%s:%s\n", lev_config_name(l), state->parity[l].path); if (state->pool[0] != 0) fprintf(stdlog, "pool:%s\n", state->pool); fflush(stdlog); diff --git a/cmdline/state.h b/cmdline/state.h index a8638b51..0e640f02 100644 --- a/cmdline/state.h +++ b/cmdline/state.h @@ -108,8 +108,7 @@ struct snapraid_state { uint32_t block_size; /**< Block size in bytes. */ unsigned raid_mode; /**< Raid mode to use. RAID_MODE_DEFAULT or RAID_MODE_ALTERNATE. */ int file_mode; /**< File access mode. Combination of MODE_* flags. */ - char parity_path[LEV_MAX][PATH_MAX]; /**< Path of the parity file. One for each parity. */ - uint64_t parity_device[LEV_MAX]; /**< Device identifier of the parity. One for each parity. */ + struct snapraid_parity parity[LEV_MAX]; /**< Parity vector. */ char share[PATH_MAX]; /**< Path of the share tree. If !=0 pool links are created in a different way. */ char pool[PATH_MAX]; /**< Path of the pool tree. */ uint64_t pool_device; /**< Device identifier of the pool. */ diff --git a/cmdline/status.c b/cmdline/status.c index d055d6b1..1e19fdd4 100644 --- a/cmdline/status.c +++ b/cmdline/status.c @@ -81,10 +81,10 @@ int state_status(struct snapraid_state* state) fprintf(stdlog, "summary:parity_block_count:%u\n", blockmax); /* get the free space on the first parity disk */ - ret = fsinfo(state->parity_path[0], 0, &free_space); + ret = fsinfo(state->parity[0].path, 0, &free_space); if (ret < 0) { /* LCOV_EXCL_START */ - fprintf(stderr, "Error accessing file '%s' to get filesystem info. %s.\n", state->parity_path[0], strerror(errno)); + fprintf(stderr, "Error accessing file '%s' to get filesystem info. %s.\n", state->parity[0].path, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } diff --git a/cmdline/sync.c b/cmdline/sync.c index f0af0927..9b8449f8 100644 --- a/cmdline/sync.c +++ b/cmdline/sync.c @@ -1055,7 +1055,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t for (l = 0; l < state->level; ++l) { /* create the file and open for writing */ parity_ptr[l] = &parity[l]; - ret = parity_create(parity_ptr[l], state->parity_path[l], &out_size, state->file_mode); + ret = parity_create(parity_ptr[l], state->parity[l].path, &out_size, state->file_mode); if (ret == -1) { /* LCOV_EXCL_START */ fprintf(stderr, "WARNING! Without an accessible %s file, it isn't possible to sync.\n", lev_name(l)); @@ -1068,7 +1068,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t /* if the file is too small */ if (out_size < loaded_size) { /* LCOV_EXCL_START */ - fprintf(stderr, "DANGER! The %s file %s is smaller than the expected %" PRId64 ".\n", lev_name(l), state->parity_path[l], loaded_size); + fprintf(stderr, "DANGER! The %s file %s is smaller than the expected %" PRId64 ".\n", lev_name(l), state->parity[l].path, loaded_size); fprintf(stderr, "If this happens because you are using an old content file,\n"); fprintf(stderr, "you can 'sync' anyway using 'snapraid --force-full sync'\n"); fprintf(stderr, "to force a full rebuild of the parity.\n");