From f719ee4f5773c15effb0f0a7ac37e6b8402be3ee Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Thu, 1 Oct 2015 23:22:21 +0200 Subject: [PATCH] Switch from deleted blocks to deleted files This will allow an easier management of the parity allocation. --- cmdline/elem.c | 32 +------------------------------- cmdline/elem.h | 17 +---------------- cmdline/scan.c | 21 +++++++++------------ cmdline/state.c | 35 +++++++++++++++++++++++------------ 4 files changed, 34 insertions(+), 71 deletions(-) diff --git a/cmdline/elem.c b/cmdline/elem.c index a101233c..d147e353 100644 --- a/cmdline/elem.c +++ b/cmdline/elem.c @@ -394,36 +394,6 @@ unsigned block_file_size(struct snapraid_block* block, unsigned block_size) return block_size; } -struct snapraid_deleted* deleted_alloc(void) -{ - struct snapraid_deleted* deleted; - - deleted = malloc_nofail(sizeof(struct snapraid_deleted)); - - /* set the state as deleted */ - deleted->block.file_mixed = BLOCK_STATE_DELETED; - - return deleted; -} - -struct snapraid_deleted* deleted_dup(struct snapraid_block* block) -{ - struct snapraid_deleted* deleted; - - deleted = deleted_alloc(); - - /* copy data from deleted block */ - deleted->block.parity_pos = block->parity_pos; - memcpy(deleted->block.hash, block->hash, HASH_SIZE); - - return deleted; -} - -void deleted_free(struct snapraid_deleted* deleted) -{ - free(deleted); -} - struct snapraid_file* file_alloc(unsigned block_size, const char* sub, data_off_t size, uint64_t mtime_sec, int mtime_nsec, uint64_t inode, uint64_t physical) { struct snapraid_file* file; @@ -752,7 +722,7 @@ struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev void disk_free(struct snapraid_disk* disk) { tommy_list_foreach(&disk->filelist, (tommy_foreach_func*)file_free); - tommy_list_foreach(&disk->deletedlist, (tommy_foreach_func*)deleted_free); + tommy_list_foreach(&disk->deletedlist, (tommy_foreach_func*)file_free); tommy_hashdyn_done(&disk->inodeset); tommy_hashdyn_done(&disk->pathset); tommy_hashdyn_done(&disk->stampset); diff --git a/cmdline/elem.h b/cmdline/elem.h index 55864715..5f488fe2 100644 --- a/cmdline/elem.h +++ b/cmdline/elem.h @@ -288,21 +288,6 @@ struct snapraid_dir { tommy_hashdyn_node nodeset; }; -/** - * Deleted entry. - */ -struct snapraid_deleted { - /** - * Deleted block. - * This block is always in state BLOCK_STATE_DELETED, - * and it's used to keep the old hash during a sync. - */ - struct snapraid_block block; - - /* nodes for data structures */ - tommy_node node; -}; - /** * Disk. */ @@ -344,7 +329,7 @@ struct snapraid_disk { tommy_list filelist; /** - * List of all the snapraid_deleted blocks for the disk. + * List of all the deleted file for the disk. * * These files are kept allocated, because the blocks are still referenced in * the ::blockarr. diff --git a/cmdline/scan.c b/cmdline/scan.c index 0c72fda6..25add9c3 100644 --- a/cmdline/scan.c +++ b/cmdline/scan.c @@ -266,7 +266,6 @@ static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_fil struct snapraid_block* block = fs_file2block_get(disk, file, i); block_off_t parity_pos = fs_file2par_get(disk, file, i); unsigned block_state; - struct snapraid_deleted* deleted; /* adjust the first free position */ /* note that doing all the deletions before alllocations, */ @@ -275,9 +274,6 @@ static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_fil if (disk->first_free_block > parity_pos) disk->first_free_block = parity_pos; - /* allocated a new deleted block from the block we are going to delete */ - deleted = deleted_dup(block); - /* in case we scan after an aborted sync, */ /* we could get also intermediate states */ block_state = block_state_get(block); @@ -299,12 +295,12 @@ static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_fil /* - File is now deleted after the aborted sync */ /* - Sync again, deleting the blocks (exactly here) */ /* with the hash of CHG block not represeting the real parity state */ - hash_invalid_set(deleted->block.hash); + hash_invalid_set(block->hash); } break; case BLOCK_STATE_REP : /* we just don't know the old hash, and then we set it to invalid */ - hash_invalid_set(deleted->block.hash); + hash_invalid_set(block->hash); break; default : /* LCOV_EXCL_START */ @@ -313,14 +309,15 @@ static void scan_file_deallocate(struct snapraid_scan* scan, struct snapraid_fil /* LCOV_EXCL_STOP */ } - /* insert it in the list of deleted blocks */ - tommy_list_insert_tail(&disk->deletedlist, &deleted->node, deleted); + /* set the block as deleted */ + block_state_set(block, BLOCK_STATE_DELETED); - /* set the deleted block in the block array */ - fs_par2block_set(disk, parity_pos, &deleted->block); + /* remove the file reference */ + block_file_set(block, 0); } - file_free(file); + /* insert it in the list of deleted blocks */ + tommy_list_insert_tail(&disk->deletedlist, &file->nodelist, file); } static void scan_file_delayed_allocate(struct snapraid_scan* scan, struct snapraid_file* file) @@ -510,7 +507,7 @@ static void scan_file_insert(struct snapraid_scan* scan, struct snapraid_file* f tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); tommy_hashdyn_insert(&disk->stampset, &file->stampset, file, file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec)); - /* delayed allocationg of the parity */ + /* delayed allocation of the parity */ scan_file_delayed_allocate(scan, file); } diff --git a/cmdline/state.c b/cmdline/state.c index 10db227d..e15a3f7b 100644 --- a/cmdline/state.c +++ b/cmdline/state.c @@ -1925,6 +1925,7 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST } else if (c == 'h') { /* hole */ uint32_t v_pos; + uint32_t i; struct snapraid_disk* disk; uint32_t mapping; @@ -1941,6 +1942,7 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST v_pos = 0; while (v_pos < blockmax) { uint32_t v_count; + struct snapraid_file* deleted; ret = sgetb32(f, &v_count); if (ret < 0) { @@ -1964,17 +1966,29 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST switch (c) { case 'o' : /* if it's a run of deleted blocks */ - while (v_count) { - struct snapraid_deleted* deleted; - /* allocate a new deleted block */ - deleted = deleted_alloc(); + /* allocate the deleted file */ + deleted = file_alloc(state->block_size, "", v_count * state->block_size, 0, 0, 0, 0); + + /* insert it in the list of deleted files */ + tommy_list_insert_tail(&disk->deletedlist, &deleted->nodelist, deleted); + + /* process all blocks */ + i = 0; + while (v_count) { + struct snapraid_block* block = &deleted->blockvec[i]; + + /* set the block as deleted */ + block_state_set(block, BLOCK_STATE_DELETED); + + /* remove the file reference */ + block_file_set(block, 0); /* set the position */ - deleted->block.parity_pos = v_pos; + block->parity_pos = v_pos; /* read the hash */ - ret = sread(f, deleted->block.hash, HASH_SIZE); + ret = sread(f, block->hash, HASH_SIZE); if (ret < 0) { /* LCOV_EXCL_START */ decoding_error(path, f); @@ -1985,7 +1999,7 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST /* if we are clearing undeterminated hashes */ if (state->clear_past_hash) { /* set the hash value to INVALID */ - hash_invalid_set(deleted->block.hash); + hash_invalid_set(block->hash); } /* we must not overwrite existing blocks */ @@ -1994,23 +2008,20 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST log_fatal("Internal inconsistency for used hole at pos %u!\n", v_pos); if (state->opt.skip_content_check) { log_fatal("Overriding as used.\n"); - deleted_free(deleted); } else { decoding_error(path, f); exit(EXIT_FAILURE); } /* LCOV_EXCL_STOP */ } else { - /* insert it in the list of deleted blocks */ - tommy_list_insert_tail(&disk->deletedlist, &deleted->node, deleted); - /* insert the block in the block array */ - fs_par2block_set(disk, v_pos, &deleted->block); + fs_par2block_set(disk, v_pos, block); } /* go to next block */ ++v_pos; --v_count; + ++i; } break; case 'O' :