From 9324933be0631787f4dede9bc20f4061d8427ce5 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Tue, 20 Aug 2013 14:25:29 +0200 Subject: [PATCH] Changes again the binary format for hole and inf --- Makefile.am | 9 +- state.c | 261 +++++++++++++++++++++++----------------------------- 2 files changed, 120 insertions(+), 150 deletions(-) diff --git a/Makefile.am b/Makefile.am index 668c3bf0..a0a72a9d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/state.c b/state.c index ae4d4f85..85ed061d 100644 --- a/state.c +++ b/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;bblockarr, b); - if (block_state_get(block) == BLOCK_STATE_DELETED) { + for(b=0;b 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)) {