mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Extend filesystem support for deallocation in the middle
This could happen in some special cases
This commit is contained in:
parent
b17e618d49
commit
25fe6a252c
4 changed files with 57 additions and 7 deletions
27
Makefile.am
27
Makefile.am
|
|
@ -227,6 +227,33 @@ if HAVE_SYMLINK
|
|||
endif
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -a check
|
||||
echo -- Filesystem allocation test
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST
|
||||
head -c 8192 /dev/zero > bench/disk2/TEST
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
# Now delete the file, and do a partial sync to force a deallocation in the middle of a file
|
||||
rm bench/disk1/TEST
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -E -S 1 -B 1 sync
|
||||
# Now force a deallocation at the end
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -E -S 7 -B 1 sync
|
||||
rm bench/disk2/TEST
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -E sync
|
||||
echo -- Filesystem fragmentation test
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST1
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST2
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST3
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST4
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST5
|
||||
head -c 8192 /dev/zero > bench/disk1/TEST6
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
# Now delete some files, and create a bigger one to fill the holes
|
||||
rm bench/disk1/TEST1
|
||||
rm bench/disk1/TEST3
|
||||
rm bench/disk1/TEST5
|
||||
head -c 65536 /dev/zero > bench/disk1/TESTX
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
|
||||
rm -r bench/disk1/TEST*
|
||||
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) -E sync
|
||||
echo --- Create some files
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 1 6 $(CHECKCOUNT) $(CHECKSIZE)
|
||||
echo DUP > bench/disk1/DUP1
|
||||
|
|
|
|||
|
|
@ -1166,7 +1166,7 @@ void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snap
|
|||
/* a chunk doesn't exist, and we have to create a new one */
|
||||
chunk = chunk_alloc(parity_pos, file, file_pos, 1);
|
||||
|
||||
/* insert te chunk in the trees */
|
||||
/* insert the chunk in the trees */
|
||||
parity_chunk = tommy_tree_insert(&disk->fs_parity, &chunk->parity_node, chunk);
|
||||
file_chunk = tommy_tree_insert(&disk->fs_file, &chunk->file_node, chunk);
|
||||
|
||||
|
|
@ -1184,6 +1184,10 @@ void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snap
|
|||
void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos)
|
||||
{
|
||||
struct snapraid_chunk* chunk;
|
||||
struct snapraid_chunk* second_chunk;
|
||||
struct snapraid_chunk* parity_chunk;
|
||||
struct snapraid_chunk* file_chunk;
|
||||
block_off_t first_count, second_count;
|
||||
|
||||
chunk = fs_par2chunk_get(disk, parity_pos);
|
||||
if (!chunk) {
|
||||
|
|
@ -1221,10 +1225,29 @@ void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos)
|
|||
return;
|
||||
}
|
||||
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when deallocating a chunk in the middle in disk '%s'\n", disk->name);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
/* otherwise it's in the middle */
|
||||
first_count = parity_pos - chunk->parity_pos;
|
||||
second_count = chunk->count - first_count - 1;
|
||||
|
||||
/* adjust the first chunk */
|
||||
chunk->count = first_count;
|
||||
|
||||
/* allocate the second chunk */
|
||||
second_chunk = chunk_alloc(chunk->parity_pos + first_count + 1, chunk->file, chunk->file_pos + first_count + 1, second_count);
|
||||
|
||||
/* insert the chunk in the trees */
|
||||
parity_chunk = tommy_tree_insert(&disk->fs_parity, &second_chunk->parity_node, second_chunk);
|
||||
file_chunk = tommy_tree_insert(&disk->fs_file, &second_chunk->file_node, second_chunk);
|
||||
|
||||
if (parity_chunk != second_chunk || file_chunk != second_chunk) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency when splitting a chunk in disk '%s'\n", disk->name);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* store the last accessed chunk */
|
||||
disk->fs_last = second_chunk;
|
||||
}
|
||||
|
||||
struct snapraid_block* fs_par2block_get(struct snapraid_disk* disk, block_off_t parity_pos)
|
||||
|
|
|
|||
|
|
@ -894,7 +894,7 @@ void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snap
|
|||
/**
|
||||
* Deallocate the parity position.
|
||||
*
|
||||
* After this call you can the par2file/par2block operations
|
||||
* After this call the par2file/par2block operations
|
||||
* won't find anymore the parity association.
|
||||
*/
|
||||
void fs_deallocate(struct snapraid_disk* disk, block_off_t pos);
|
||||
|
|
|
|||
|
|
@ -1403,7 +1403,7 @@ static int position_is_required(struct snapraid_state* state, block_off_t pos)
|
|||
* Checks if the info block is REQUIREQ.
|
||||
*
|
||||
* This is used to ensure that we keep the last check used for scrubbing.
|
||||
* and the we add it when importing old context files.
|
||||
* and that we add it when importing old context files.
|
||||
*
|
||||
* Note that you can have position without info blocks, for example
|
||||
* if all the blocks are not synced.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue