mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Switch from deleted blocks to deleted files
This will allow an easier management of the parity allocation.
This commit is contained in:
parent
23983d6e9c
commit
f719ee4f57
4 changed files with 34 additions and 71 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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' :
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue