Switch from deleted blocks to deleted files

This will allow an easier management of the parity allocation.
This commit is contained in:
Andrea Mazzoleni 2015-10-01 23:22:21 +02:00
parent 23983d6e9c
commit f719ee4f57
4 changed files with 34 additions and 71 deletions

View file

@ -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);

View file

@ -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.

View file

@ -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);
}

View file

@ -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' :