mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
Changes again the binary format for hole and inf
This commit is contained in:
parent
cab5309fd2
commit
9324933be0
2 changed files with 120 additions and 150 deletions
|
|
@ -233,13 +233,14 @@ endif
|
|||
rm test/disk1/4*
|
||||
rm test/disk2/5*
|
||||
rm test/disk3/6*
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -t 10 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-content-text test-rewrite
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 4 3 $(CHECKCOUNT) $(CHECKSIZE)
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -t 100 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-content-text -t 700 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --test-force-content-text test-rewrite
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -t 100 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -t 1000 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check -l test.log
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check
|
||||
echo --- Rehash to spooky2 and rehash even blocks
|
||||
|
|
|
|||
261
state.c
261
state.c
|
|
@ -1718,7 +1718,6 @@ static void state_write_text(struct snapraid_state* state, STREAM* f)
|
|||
tommy_node* j;
|
||||
struct snapraid_disk* disk = i->data;
|
||||
int first_deleted;
|
||||
block_off_t blockdiskmax;
|
||||
|
||||
/* for each file */
|
||||
for(j=disk->filelist;j!=0;j=j->next) {
|
||||
|
|
@ -1838,18 +1837,12 @@ static void state_write_text(struct snapraid_state* state, STREAM* f)
|
|||
++count_dir;
|
||||
}
|
||||
|
||||
/* maximum block for this disk */
|
||||
blockdiskmax = tommy_array_size(&disk->blockarr);
|
||||
|
||||
/* skip blocks over the end of the parity */
|
||||
if (blockdiskmax > blockmax)
|
||||
blockdiskmax = blockmax;
|
||||
|
||||
/* for each deleted block in the disk */
|
||||
first_deleted = 1;
|
||||
for(b=0;b<blockdiskmax;++b) {
|
||||
struct snapraid_block* block = tommy_array_get(&disk->blockarr, b);
|
||||
if (block_state_get(block) == BLOCK_STATE_DELETED) {
|
||||
for(b=0;b<blockmax;++b) {
|
||||
if (is_block_deleted(disk, b)) {
|
||||
struct snapraid_block* block = disk_block_get(disk, b);
|
||||
|
||||
if (first_deleted) {
|
||||
first_deleted = 0;
|
||||
|
||||
|
|
@ -1875,7 +1868,7 @@ static void state_write_text(struct snapraid_state* state, STREAM* f)
|
|||
}
|
||||
}
|
||||
|
||||
/* for each block */
|
||||
/* write the info for each block */
|
||||
for(b=0;b<blockmax;++b) {
|
||||
/* if the position is used */
|
||||
if (is_block_used(state, b)) {
|
||||
|
|
@ -2205,12 +2198,6 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = sgetb32(f, &blockmax);
|
||||
if (ret < 0) {
|
||||
decoding_error(path, f);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
v_pos = 0;
|
||||
while (v_pos < blockmax) {
|
||||
int rehash;
|
||||
|
|
@ -2273,7 +2260,6 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
|
|||
} else if (c == 'h') {
|
||||
/* hole */
|
||||
uint32_t v_pos;
|
||||
block_off_t blockdiskmax;
|
||||
struct snapraid_disk* disk;
|
||||
|
||||
ret = sgetbs(f, buffer, sizeof(buffer));
|
||||
|
|
@ -2290,23 +2276,11 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = sgetb32(f, &blockdiskmax);
|
||||
if (ret < 0) {
|
||||
decoding_error(path, f);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (blockdiskmax > blockmax) {
|
||||
fprintf(stderr, "Internal inconsistency in disk size!\n");
|
||||
decoding_error(path, f);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* grow the array */
|
||||
tommy_array_grow(&disk->blockarr, blockdiskmax);
|
||||
tommy_array_grow(&disk->blockarr, blockmax);
|
||||
|
||||
v_pos = 0;
|
||||
while (v_pos < blockdiskmax) {
|
||||
while (v_pos < blockmax) {
|
||||
uint32_t v_count;
|
||||
|
||||
ret = sgetb32(f, &v_count);
|
||||
|
|
@ -2315,7 +2289,7 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (v_pos + v_count > blockdiskmax) {
|
||||
if (v_pos + v_count > blockmax) {
|
||||
decoding_error(path, f);
|
||||
fprintf(stderr, "Internal inconsistency in hole size!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -2566,6 +2540,12 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
|
|||
fprintf(stderr, "Please restore the 'block_size' value in the configuration file to '%u'\n", blksize / 1024);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if (c == 'x') {
|
||||
ret = sgetb32(f, &blockmax);
|
||||
if (ret < 0) {
|
||||
decoding_error(path, f);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if (c == 'm') {
|
||||
struct snapraid_map* map;
|
||||
char uuid[UUID_MAX];
|
||||
|
|
@ -2701,8 +2681,11 @@ static void state_write_binary(struct snapraid_state* state, STREAM* f)
|
|||
/* write header */
|
||||
swrite("SNAPCNT1\n\3\0\0", 12, f);
|
||||
|
||||
/* write block size and block max */
|
||||
sputc('z', f);
|
||||
sputb32(state->block_size, f);
|
||||
sputc('x', f);
|
||||
sputb32(blockmax, f);
|
||||
if (serror(f)) {
|
||||
fprintf(stderr, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -2757,65 +2740,10 @@ static void state_write_binary(struct snapraid_state* state, STREAM* f)
|
|||
}
|
||||
}
|
||||
|
||||
/* save the info */
|
||||
sputc('i', f);
|
||||
|
||||
sputb32(info_oldest, f);
|
||||
|
||||
/* write blockmax, this is also going to be used in a lot of checks */
|
||||
sputb32(blockmax, f);
|
||||
|
||||
/* write the info for each block */
|
||||
begin = 0;
|
||||
while (begin < blockmax) {
|
||||
snapraid_info info;
|
||||
block_off_t end;
|
||||
time_t t;
|
||||
unsigned flag;
|
||||
|
||||
info = info_get(&state->infoarr, begin);
|
||||
|
||||
/* find the end of run of blocks */
|
||||
end = begin + 1;
|
||||
while (end < blockmax
|
||||
&& info == info_get(&state->infoarr, end))
|
||||
{
|
||||
++end;
|
||||
}
|
||||
|
||||
sputb32(end - begin, f);
|
||||
|
||||
/* if there is info */
|
||||
if (info) {
|
||||
/* other flags */
|
||||
flag = 1; /* info is present */
|
||||
if (info_get_bad(info))
|
||||
flag |= 2;
|
||||
if (info_get_rehash(info))
|
||||
flag |= 4;
|
||||
sputb32(flag, f);
|
||||
|
||||
t = info_get_time(info) - info_oldest;
|
||||
sputb32(t, f);
|
||||
} else {
|
||||
/* write a special 0 flag to mark missing info */
|
||||
sputb32(0, f);
|
||||
}
|
||||
|
||||
if (serror(f)) {
|
||||
fprintf(stderr, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* next begin position */
|
||||
begin = end;
|
||||
}
|
||||
|
||||
/* for each disk */
|
||||
for(i=state->disklist;i!=0;i=i->next) {
|
||||
tommy_node* j;
|
||||
struct snapraid_disk* disk = i->data;
|
||||
block_off_t blockdiskmax;
|
||||
|
||||
/* for each file */
|
||||
for(j=disk->filelist;j!=0;j=j->next) {
|
||||
|
|
@ -2940,77 +2868,118 @@ static void state_write_binary(struct snapraid_state* state, STREAM* f)
|
|||
++count_dir;
|
||||
}
|
||||
|
||||
/* maximum block for this disk */
|
||||
blockdiskmax = tommy_array_size(&disk->blockarr);
|
||||
/* write the deleted info for each block */
|
||||
begin = 0;
|
||||
while (begin < blockmax) {
|
||||
int is_deleted;
|
||||
block_off_t end;
|
||||
|
||||
/* skip blocks over the end of the parity */
|
||||
if (blockdiskmax > blockmax)
|
||||
blockdiskmax = blockmax;
|
||||
is_deleted = is_block_deleted(disk, begin);
|
||||
|
||||
/* skip empty blocks at the end of the disk */
|
||||
while (blockdiskmax > 0 && disk_block_get(disk, blockdiskmax - 1) == BLOCK_EMPTY)
|
||||
--blockdiskmax;
|
||||
|
||||
/* write the hole list only if the disk is not completely empty */
|
||||
/* this is required to write no reference to a removed disk */
|
||||
if (blockdiskmax) {
|
||||
/* write the list of deleted blocks */
|
||||
sputc('h', f);
|
||||
sputbs(disk->name, f);
|
||||
sputb32(blockdiskmax, f);
|
||||
|
||||
if (serror(f)) {
|
||||
fprintf(stderr, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* find the end of run of blocks */
|
||||
end = begin + 1;
|
||||
while (end < blockmax
|
||||
&& is_deleted == is_block_deleted(disk, end))
|
||||
{
|
||||
++end;
|
||||
}
|
||||
|
||||
/* write the deleted info for each block */
|
||||
begin = 0;
|
||||
while (begin < blockdiskmax) {
|
||||
int is_deleted;
|
||||
block_off_t end;
|
||||
|
||||
is_deleted = is_block_deleted(disk, begin);
|
||||
|
||||
/* find the end of run of blocks */
|
||||
end = begin + 1;
|
||||
while (end < blockdiskmax
|
||||
&& is_deleted == is_block_deleted(disk, end))
|
||||
{
|
||||
++end;
|
||||
}
|
||||
|
||||
sputb32(end - begin, f);
|
||||
|
||||
if (is_deleted) {
|
||||
/* write the run of deleted blocks with hash */
|
||||
sputc('o', f);
|
||||
|
||||
/* write all the hash */
|
||||
while (begin < end) {
|
||||
struct snapraid_block* block = disk_block_get(disk, begin);
|
||||
|
||||
swrite(block->hash, HASH_SIZE, f);
|
||||
|
||||
++begin;
|
||||
}
|
||||
} else {
|
||||
/* write the run of blocks without hash */
|
||||
/* they can be either used or empty blocks */
|
||||
sputc('O', f);
|
||||
|
||||
/* next begin position */
|
||||
begin = end;
|
||||
/* if it's the first iteration */
|
||||
if (begin == 0) {
|
||||
/* if there is no deleted block in the disk, write nothing */
|
||||
/* this is required to avoid to have references to a completely empty disk */
|
||||
if (end == blockmax && !is_deleted) {
|
||||
/* exit */
|
||||
break;
|
||||
}
|
||||
|
||||
/* write the hole header only if required */
|
||||
sputc('h', f);
|
||||
sputbs(disk->name, f);
|
||||
if (serror(f)) {
|
||||
fprintf(stderr, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
sputb32(end - begin, f);
|
||||
|
||||
if (is_deleted) {
|
||||
/* write the run of deleted blocks with hash */
|
||||
sputc('o', f);
|
||||
|
||||
/* write all the hash */
|
||||
while (begin < end) {
|
||||
struct snapraid_block* block = disk_block_get(disk, begin);
|
||||
|
||||
swrite(block->hash, HASH_SIZE, f);
|
||||
|
||||
++begin;
|
||||
}
|
||||
} else {
|
||||
/* write the run of blocks without hash */
|
||||
/* they can be either used or empty blocks */
|
||||
sputc('O', f);
|
||||
|
||||
/* next begin position */
|
||||
begin = end;
|
||||
}
|
||||
|
||||
if (serror(f)) {
|
||||
fprintf(stderr, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* write the info for each block */
|
||||
sputc('i', f);
|
||||
sputb32(info_oldest, f);
|
||||
begin = 0;
|
||||
while (begin < blockmax) {
|
||||
snapraid_info info;
|
||||
block_off_t end;
|
||||
time_t t;
|
||||
unsigned flag;
|
||||
|
||||
info = info_get(&state->infoarr, begin);
|
||||
|
||||
/* find the end of run of blocks */
|
||||
end = begin + 1;
|
||||
while (end < blockmax
|
||||
&& info == info_get(&state->infoarr, end))
|
||||
{
|
||||
++end;
|
||||
}
|
||||
|
||||
sputb32(end - begin, f);
|
||||
|
||||
/* if there is info */
|
||||
if (info) {
|
||||
/* other flags */
|
||||
flag = 1; /* info is present */
|
||||
if (info_get_bad(info))
|
||||
flag |= 2;
|
||||
if (info_get_rehash(info))
|
||||
flag |= 4;
|
||||
sputb32(flag, f);
|
||||
|
||||
t = info_get_time(info) - info_oldest;
|
||||
sputb32(t, f);
|
||||
} else {
|
||||
/* write a special 0 flag to mark missing info */
|
||||
sputb32(0, f);
|
||||
}
|
||||
|
||||
if (serror(f)) {
|
||||
fprintf(stderr, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* next begin position */
|
||||
begin = end;
|
||||
}
|
||||
|
||||
sputc('N', f);
|
||||
sputble32(scrc(f), f);
|
||||
if (serror(f)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue