mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Checks the parity size in sync.
This commit is contained in:
parent
c5575d2095
commit
91e74e91b8
8 changed files with 89 additions and 27 deletions
2
HISTORY
2
HISTORY
|
|
@ -20,6 +20,8 @@ SnapRAID HISTORY
|
|||
* Always fill the memory after allocating it to avoid the OOM (Out Of Memory)
|
||||
killer in Linux.
|
||||
* Fixed compilation in Solaris for lacking both futimes() and futimens().
|
||||
* Now 'sync' ensures that the parity file are not too small to contains the
|
||||
loaded data.
|
||||
|
||||
1.12 2012/9
|
||||
=============
|
||||
|
|
|
|||
19
check.c
19
check.c
|
|
@ -1187,6 +1187,7 @@ void state_check(struct snapraid_state* state, int check, int fix, block_off_t b
|
|||
{
|
||||
block_off_t blockmax;
|
||||
data_off_t size;
|
||||
data_off_t out_size;
|
||||
int ret;
|
||||
struct snapraid_parity parity;
|
||||
struct snapraid_parity qarity;
|
||||
|
|
@ -1201,7 +1202,7 @@ void state_check(struct snapraid_state* state, int check, int fix, block_off_t b
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
blockmax = parity_resize(state);
|
||||
blockmax = parity_size(state);
|
||||
size = blockmax * (data_off_t)state->block_size;
|
||||
|
||||
if (blockstart > blockmax) {
|
||||
|
|
@ -1218,19 +1219,31 @@ void state_check(struct snapraid_state* state, int check, int fix, block_off_t b
|
|||
/* if fixing, create the file and open for writing */
|
||||
/* if it fails, we cannot continue */
|
||||
parity_ptr = &parity;
|
||||
ret = parity_create(parity_ptr, state->parity, size, 0);
|
||||
ret = parity_create(parity_ptr, state->parity, &out_size);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "WARNING! Without an accessible Parity file, it isn't possible to fix any error.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = parity_chsize(parity_ptr, size, &out_size);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "WARNING! Without an accessible Parity file, it isn't possible to sync.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->level >= 2) {
|
||||
qarity_ptr = &qarity;
|
||||
ret = parity_create(qarity_ptr, state->qarity, size, 0);
|
||||
ret = parity_create(qarity_ptr, state->qarity, &out_size);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "WARNING! Without an accessible Q-Parity file, it isn't possible to fix any error.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = parity_chsize(qarity_ptr, size, &out_size);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "WARNING! Without an accessible Q-Parity file, it isn't possible to sync.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
qarity_ptr = 0;
|
||||
}
|
||||
|
|
|
|||
2
dry.c
2
dry.c
|
|
@ -156,7 +156,7 @@ void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
|
||||
printf("Drying...\n");
|
||||
|
||||
blockmax = parity_resize(state);
|
||||
blockmax = parity_size(state);
|
||||
|
||||
if (blockstart > blockmax) {
|
||||
fprintf(stderr, "Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
|
||||
|
|
|
|||
31
parity.c
31
parity.c
|
|
@ -24,7 +24,7 @@
|
|||
/****************************************************************************/
|
||||
/* parity */
|
||||
|
||||
block_off_t parity_resize(struct snapraid_state* state)
|
||||
block_off_t parity_size(struct snapraid_state* state)
|
||||
{
|
||||
block_off_t parity_block;
|
||||
tommy_node* i;
|
||||
|
|
@ -90,15 +90,12 @@ void parity_overflow(struct snapraid_state* state, data_off_t size)
|
|||
}
|
||||
}
|
||||
|
||||
int parity_create(struct snapraid_parity* parity, const char* path, data_off_t size, data_off_t* out_size)
|
||||
int parity_create(struct snapraid_parity* parity, const char* path, data_off_t* out_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pathcpy(parity->path, sizeof(parity->path), path);
|
||||
|
||||
if (out_size)
|
||||
*out_size = 0;
|
||||
|
||||
/* opening in sequential mode in Windows */
|
||||
parity->f = open(parity->path, O_RDWR | O_CREAT | O_BINARY | O_SEQUENTIAL, 0600);
|
||||
if (parity->f == -1) {
|
||||
|
|
@ -115,8 +112,20 @@ int parity_create(struct snapraid_parity* parity, const char* path, data_off_t s
|
|||
|
||||
/* get the size of the existing data */
|
||||
parity->valid_size = parity->st.st_size;
|
||||
if (out_size)
|
||||
*out_size = parity->st.st_size;
|
||||
*out_size = parity->st.st_size;
|
||||
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
close(parity->f);
|
||||
parity->f = -1;
|
||||
parity->valid_size = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int parity_chsize(struct snapraid_parity* parity, data_off_t size, data_off_t* out_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (parity->st.st_size < size) {
|
||||
int f_ret;
|
||||
|
|
@ -158,8 +167,7 @@ int parity_create(struct snapraid_parity* parity, const char* path, data_off_t s
|
|||
}
|
||||
|
||||
/* return the new size */
|
||||
if (out_size)
|
||||
*out_size = parity->st.st_size;
|
||||
*out_size = parity->st.st_size;
|
||||
|
||||
/* now check the error */
|
||||
if (f_ret != 0) {
|
||||
|
|
@ -185,8 +193,7 @@ int parity_create(struct snapraid_parity* parity, const char* path, data_off_t s
|
|||
}
|
||||
|
||||
/* return the new real size */
|
||||
if (out_size)
|
||||
*out_size = parity->st.st_size;
|
||||
*out_size = parity->st.st_size;
|
||||
|
||||
/* adjust the valid to the new size */
|
||||
parity->valid_size = size;
|
||||
|
|
@ -204,8 +211,6 @@ int parity_create(struct snapraid_parity* parity, const char* path, data_off_t s
|
|||
return 0;
|
||||
|
||||
bail:
|
||||
close(parity->f);
|
||||
parity->f = -1;
|
||||
parity->valid_size = 0;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
12
parity.h
12
parity.h
|
|
@ -31,7 +31,7 @@ struct snapraid_parity {
|
|||
/**
|
||||
* Computes the size of the parity data in number of blocks.
|
||||
*/
|
||||
block_off_t parity_resize(struct snapraid_state* state);
|
||||
block_off_t parity_size(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Reports all the files outside the specified parity size.
|
||||
|
|
@ -40,9 +40,15 @@ void parity_overflow(struct snapraid_state* state, data_off_t size);
|
|||
|
||||
/**
|
||||
* Creates the parity file.
|
||||
* \param out_size Return the final size of the parity file. Returned also in error cases.
|
||||
* \param out_size Return the size of the parity file.
|
||||
*/
|
||||
int parity_create(struct snapraid_parity* parity, const char* path, data_off_t size, data_off_t* out_size);
|
||||
int parity_create(struct snapraid_parity* parity, const char* path, data_off_t* out_size);
|
||||
|
||||
/**
|
||||
* Changes the parity size.
|
||||
* \param out_size Return the size of the parity file. The out_size is set also on error to reflect a partial resize.
|
||||
*/
|
||||
int parity_chsize(struct snapraid_parity* parity, data_off_t size, data_off_t* out_size);
|
||||
|
||||
/**
|
||||
* Opens an already existing parity file.
|
||||
|
|
|
|||
9
state.c
9
state.c
|
|
@ -44,6 +44,7 @@ void state_init(struct snapraid_state* state)
|
|||
tommy_list_init(&state->maplist);
|
||||
tommy_list_init(&state->contentlist);
|
||||
tommy_list_init(&state->filterlist);
|
||||
state->loaded_blockmax = 0;
|
||||
}
|
||||
|
||||
void state_done(struct snapraid_state* state)
|
||||
|
|
@ -645,6 +646,7 @@ void state_read(struct snapraid_state* state)
|
|||
struct snapraid_disk* disk;
|
||||
struct snapraid_file* file;
|
||||
block_off_t blockidx;
|
||||
block_off_t blockmax;
|
||||
unsigned line;
|
||||
unsigned count_file;
|
||||
unsigned count_block;
|
||||
|
|
@ -707,6 +709,7 @@ void state_read(struct snapraid_state* state)
|
|||
file = 0;
|
||||
line = 1;
|
||||
blockidx = 0;
|
||||
blockmax = 0;
|
||||
|
||||
while (1) {
|
||||
char buffer[PATH_MAX];
|
||||
|
|
@ -748,6 +751,10 @@ void state_read(struct snapraid_state* state)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* keep track of the max block number */
|
||||
if (blockidx > blockmax)
|
||||
blockmax = blockidx;
|
||||
|
||||
block = &file->blockvec[blockidx];
|
||||
|
||||
if (block->parity_pos != POS_INVALID) {
|
||||
|
|
@ -1191,6 +1198,8 @@ void state_read(struct snapraid_state* state)
|
|||
|
||||
sclose(f);
|
||||
|
||||
state->loaded_blockmax = blockmax;
|
||||
|
||||
/* update the mapping */
|
||||
state_map(state);
|
||||
|
||||
|
|
|
|||
1
state.h
1
state.h
|
|
@ -51,6 +51,7 @@ struct snapraid_state {
|
|||
tommy_list disklist; /**< List of all the disks. */
|
||||
tommy_list maplist; /**< List of all the disk mappings. */
|
||||
tommy_list filterlist; /**< List of inclusion/exclusion. */
|
||||
block_off_t loaded_blockmax; /**< Previous size of the parity file, computed from the loaded state. */
|
||||
time_t progress_start; /**< Start of processing for progress visualization. */
|
||||
time_t progress_last; /**< Last update of progress visualization. */
|
||||
time_t progress_interruption; /**< Start of the measure interruption. */
|
||||
|
|
|
|||
40
sync.c
40
sync.c
|
|
@ -352,8 +352,9 @@ bail:
|
|||
int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount)
|
||||
{
|
||||
block_off_t blockmax;
|
||||
data_off_t loaded_size;
|
||||
data_off_t size;
|
||||
data_off_t size_after;
|
||||
data_off_t out_size;
|
||||
tommy_node* i;
|
||||
int ret;
|
||||
struct snapraid_parity parity;
|
||||
|
|
@ -364,10 +365,11 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
|
||||
printf("Initializing...\n");
|
||||
|
||||
blockmax = parity_resize(state);
|
||||
blockmax = parity_size(state);
|
||||
size = blockmax * (data_off_t)state->block_size;
|
||||
loaded_size = state->loaded_blockmax * (data_off_t)state->block_size;
|
||||
|
||||
/* remove all the deleted blocks over the upper limit */
|
||||
/* remove all the deleted blocks over the new parity size */
|
||||
for(i=state->disklist;i!=0;i=i->next) {
|
||||
struct snapraid_disk* disk = i->data;
|
||||
block_off_t diskblockmax = tommy_array_size(&disk->blockarr);
|
||||
|
|
@ -395,18 +397,42 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
|
||||
/* create the file and open for writing */
|
||||
parity_ptr = &parity;
|
||||
ret = parity_create(parity_ptr, state->parity, size, &size_after);
|
||||
ret = parity_create(parity_ptr, state->parity, &out_size);
|
||||
if (ret == -1) {
|
||||
parity_overflow(state, size_after);
|
||||
fprintf(stderr, "WARNING! Without an accessible Parity file, it isn't possible to sync.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* if the file is too small */
|
||||
if (out_size < loaded_size) {
|
||||
fprintf(stderr, "DANGER! The Parity file %s is smaller than the expected %lld.\n", state->parity, loaded_size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = parity_chsize(parity_ptr, size, &out_size);
|
||||
if (ret == -1) {
|
||||
parity_overflow(state, out_size);
|
||||
fprintf(stderr, "WARNING! Without an accessible Parity file, it isn't possible to sync.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (state->level >= 2) {
|
||||
qarity_ptr = &qarity;
|
||||
ret = parity_create(qarity_ptr, state->qarity, size, &size_after);
|
||||
ret = parity_create(qarity_ptr, state->qarity, &out_size);
|
||||
if (ret == -1) {
|
||||
parity_overflow(state, size_after);
|
||||
fprintf(stderr, "WARNING! Without an accessible Q-Parity file, it isn't possible to sync.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* if the file is too small */
|
||||
if (out_size < loaded_size) {
|
||||
fprintf(stderr, "DANGER! The Q-Parity file %s is smaller than the expected %lld.\n", state->qarity, loaded_size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = parity_chsize(qarity_ptr, size, &out_size);
|
||||
if (ret == -1) {
|
||||
parity_overflow(state, out_size);
|
||||
fprintf(stderr, "WARNING! Without an accessible Q-Parity file, it isn't possible to sync.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue