mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Reallocates files after a failed sync.
This commit is contained in:
parent
e55723ecdd
commit
bbe151792c
3 changed files with 70 additions and 4 deletions
3
HISTORY
3
HISTORY
|
|
@ -9,6 +9,9 @@ SnapRAID HISTORY
|
|||
positive when searching for inode/timestamp/size.
|
||||
* Allow to run a fix command with disks that doesn't need to be
|
||||
fixed mounted as read-only.
|
||||
* After a failed sync, always reallocates new files with a not
|
||||
yet computed parity to ensure to minimize the parity usage,
|
||||
if some other file is deleted in the meantime.
|
||||
* Doesn't count empty dirs as files in the diff counters.
|
||||
* Added a new "share" configuration option to allow to share
|
||||
in the network the pool directory also in Windows.
|
||||
|
|
|
|||
2
elem.h
2
elem.h
|
|
@ -70,8 +70,6 @@ struct snapraid_filter {
|
|||
/**
|
||||
* The block has both the hash and the parity computed.
|
||||
* This is the normal state of a saved block.
|
||||
* Note that if exists at least one BLOCK_STATE_BLK in a disk, all the other
|
||||
* blocks at the same address in other disks can be only BLOCK_STATE_EMPTY or BLOCK_STATE_BLK.
|
||||
*
|
||||
* The block hash field IS set.
|
||||
* The parity for this disk is updated.
|
||||
|
|
|
|||
69
scan.c
69
scan.c
|
|
@ -140,9 +140,9 @@ static void scan_link(struct snapraid_scan* scan, struct snapraid_state* state,
|
|||
}
|
||||
|
||||
/**
|
||||
* Removes the specified file from the data set.
|
||||
* Removes the specified file from the parity.
|
||||
*/
|
||||
static void scan_file_remove(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
|
||||
static void scan_file_deallocate(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
|
||||
{
|
||||
block_off_t i;
|
||||
|
||||
|
|
@ -202,6 +202,65 @@ static void scan_file_remove(struct snapraid_state* state, struct snapraid_disk*
|
|||
/* set the deleted block in the block array */
|
||||
tommy_arrayblk_set(&disk->blockarr, block_pos, &deleted->block);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a file is completely formed of NEW or CHG blocks,
|
||||
* and if it has at least one block.
|
||||
*/
|
||||
static int file_is_full_invalid(struct snapraid_file* file)
|
||||
{
|
||||
block_off_t i;
|
||||
|
||||
/* if no block, the file is valid */
|
||||
if (file->blockmax == 0)
|
||||
return 0;
|
||||
|
||||
/* check all blocks */
|
||||
/* it should be enough to check only the first one */
|
||||
/* because updates are always in forward direction, */
|
||||
/* but we check all just to be sure */
|
||||
for(i=0;i<file->blockmax;++i) {
|
||||
struct snapraid_block* block = &file->blockvec[i];
|
||||
unsigned block_state;
|
||||
|
||||
block_state = block_state_get(block);
|
||||
|
||||
if (block_state != BLOCK_STATE_NEW && block_state != BLOCK_STATE_CHG)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps the file as it's (or with only a name/inode modification).
|
||||
* If a file contains only NEW blocks, it's reallocated to ensure
|
||||
* to always minimize the space used in the parity.
|
||||
* This could happen after a failed sync, when some other file is deleted,
|
||||
* and then new ones can be moved to fill the hole created.
|
||||
*/
|
||||
static void scan_file_keep(struct snapraid_scan* scan, struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
|
||||
{
|
||||
if (file_is_full_invalid(file)) {
|
||||
/* deallocate the file from the parity */
|
||||
scan_file_deallocate(state, disk, file);
|
||||
|
||||
/* remove the file from the list */
|
||||
tommy_list_remove_existing(&disk->filelist, &file->nodelist);
|
||||
|
||||
/* insert the file in the delayed block allocation */
|
||||
tommy_list_insert_tail(&scan->file_insert_list, &file->nodelist, file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified file from the data set.
|
||||
*/
|
||||
static void scan_file_remove(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
|
||||
{
|
||||
/* deallocate the file from the parity */
|
||||
scan_file_deallocate(state, disk, file);
|
||||
|
||||
/* remove the file from the file containers */
|
||||
if (!file_flag_has(file, FILE_IS_WITHOUT_INODE)) {
|
||||
|
|
@ -391,6 +450,9 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
|
|||
}
|
||||
}
|
||||
|
||||
/* mark the file as kept */
|
||||
scan_file_keep(scan, state, disk, file);
|
||||
|
||||
/* nothing more to do */
|
||||
return;
|
||||
}
|
||||
|
|
@ -514,6 +576,9 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
|
|||
}
|
||||
}
|
||||
|
||||
/* mark the file as kept */
|
||||
scan_file_keep(scan, state, disk, file);
|
||||
|
||||
/* nothing more to do */
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue