diff --git a/HISTORY b/HISTORY index 121a052b..3530cee2 100644 --- a/HISTORY +++ b/HISTORY @@ -5,6 +5,7 @@ SnapRAID HISTORY ========== * Fixed the restore of directory with unicode chars in Windows. * Fixed support of file names starting or ending with a space. +* Removes files before inserting new ones to minimize the parity size. 1.2 2011/5 ========== diff --git a/scan.c b/scan.c index 521a5afb..40639f84 100644 --- a/scan.c +++ b/scan.c @@ -22,11 +22,16 @@ #include "state.h" struct snapraid_scan { + /** + * Counters of changes. + */ unsigned count_equal; unsigned count_moved; unsigned count_change; unsigned count_remove; unsigned count_insert; + + tommy_list insert_list; /**< Files to insert. */ }; /** @@ -151,6 +156,8 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, /* otherwise it's equal */ ++scan->count_equal; } + + /* nothing more to do */ return; } else { /* do a safety check to ensure that the common ext4 case of zeroing */ @@ -167,23 +174,26 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, } } - /* remove and reinsert it */ + /* remove it */ ++scan->count_change; - --scan->count_insert; scan_file_remove(state, disk, file); - /* continue to insert it */ + + /* and continue to reinsert it */ } + } else { + /* create the new file */ + ++scan->count_insert; + + /* and continue to insert it */ } - /* create the new file */ - ++scan->count_insert; file = file_alloc(state->block_size, sub, st->st_size, st->st_mtime, st->st_ino); /* mark it as present */ file_flag_set(file, FILE_IS_PRESENT); - /* insert it */ - scan_file_insert(state, disk, file); + /* insert it in the delayed insert list */ + tommy_list_insert_tail(&scan->insert_list, &file->nodelist, file); } /** @@ -300,6 +310,7 @@ void state_scan(struct snapraid_state* state) scan[i].count_change = 0; scan[i].count_remove = 0; scan[i].count_insert = 0; + tommy_list_init(&scan[i].insert_list); } for(i=0;idata; + + /* next node */ + node = node->next; + + /* insert it */ + scan_file_insert(state, disk, file); + } + /* if all the previous file were removed */ if (scan[i].count_equal == 0 && scan[i].count_moved == 0 && scan[i].count_remove != 0) { if (!state->force_empty) {