diff --git a/HISTORY b/HISTORY index 55284793..ae4daac7 100644 --- a/HISTORY +++ b/HISTORY @@ -12,7 +12,10 @@ SnapRAID HISTORY * Changed to a binary content file to improve speed and reduce size. * Added a hash seed to make harder intentional collision attacks. * When insering files for the first time, sort them by their physical - address to improve read performance. + address to improve read performance. + * Removed the --find-by-name, -N option. Now it automatically searches + by name if a file is not found searching by inode, automatically + reassigning inodes in restored files. * Better selection of the RAID6 implementation for different CPUs. * Added RAID5/RAID6 mmx and sse2 implementations with unrolling by 4. They are a little faster than the previous unroll by 2. diff --git a/Makefile.am b/Makefile.am index 4a466b62..026cda31 100644 --- a/Makefile.am +++ b/Makefile.am @@ -178,10 +178,10 @@ endif $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf -p 100 scrub rm test/disk1/content $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync - echo --- Make a hole in the disk array + echo --- Make a hole in the disk array and sync with --force-empty mv test/disk2 test/disk2.old mkdir test/disk2 - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --force-empty -c $(srcdir)/test-raid6.conf sync + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf --force-empty sync $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check echo --- Use with the hole $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6-hole.conf sync @@ -228,9 +228,7 @@ endif $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf fix -l test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid5.conf check $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check - echo --- Sync after all the fixes with an empty drive to test --find-by-name - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --find-by-name -c $(srcdir)/test-raid6.conf sync - $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync echo --- Delete some files and create some new, sync and check in multiple steps rm test/disk1/4* rm test/disk2/5* diff --git a/TODO b/TODO index 6ac7fb72..06851850 100644 --- a/TODO +++ b/TODO @@ -9,16 +9,6 @@ This is the list of TODO items for SnapRAID. But see: http://unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4 coreutils stat has an example, but it doesn't work in Linux (see lib/stat-time.h) -* Drop inode requirement ? -To identify renamed file we can use the nanosecond modification time as alternative way. -Like equality of: -- size + inode + modification time in second -OR -- size + modification time in second + modification time in nanosecond (if different than 0) -This will allow to run with mismatching inodes like in FUSE. -The risk is to have a lot of nanosecond fields to 0. For example, CP doesn't copy it. -But it doesn't seem a problem. In such cases you won't get the rename optimization. - * Add a way to list the content of the array. A new "list" command ? Something similar at "diff" and "dup". diff --git a/elem.h b/elem.h index dcb80e64..67d805a0 100644 --- a/elem.h +++ b/elem.h @@ -196,6 +196,15 @@ struct snapraid_block { #define FILE_IS_JUNCTION 0x800 /**< If it's a junction for Windows. Not yet supported. */ #define FILE_IS_LINK_MASK 0xF00 /**< Mask for link type. */ +/** + * If the file is without inode. + * It could happen in filesystem where inodes are not persistent, + * or when restoring a full disk with "fix". + * In such cases we have to clear any stored duplicate inode. + * After the scan process completes, no file should have this flag set. + */ +#define FILE_IS_WITHOUT_INODE 0x1000 + /** * File. */ diff --git a/scan.c b/scan.c index ff0891d4..3ce9f96c 100644 --- a/scan.c +++ b/scan.c @@ -25,11 +25,12 @@ struct snapraid_scan { /** * Counters of changes. */ - unsigned count_equal; - unsigned count_moved; - unsigned count_change; - unsigned count_remove; - unsigned count_insert; + unsigned count_equal; /**< Files equal. */ + unsigned count_move; /**< Files with a different name, but equal inode, size and timestamp. */ + unsigned count_restore; /**< Files with equal name, size and timestamp, but different inode. */ + unsigned count_change; /**< Files modified. */ + unsigned count_remove; /**< Files removed. */ + unsigned count_insert; /**< Files new. */ tommy_list file_insert_list; /**< Files to insert. */ tommy_list link_insert_list; /**< Links to insert. */ @@ -203,7 +204,9 @@ static void scan_file_remove(struct snapraid_state* state, struct snapraid_disk* } /* remove the file from the file containers */ - tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); + if (!file_flag_has(file, FILE_IS_WITHOUT_INODE)) { + tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); + } tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset); tommy_list_remove_existing(&disk->filelist, &file->nodelist); @@ -273,40 +276,38 @@ static void scan_file_insert(struct snapraid_state* state, struct snapraid_disk* static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, int output, struct snapraid_disk* disk, const char* sub, const struct stat* st, uint64_t physical) { struct snapraid_file* file; + uint64_t inode = st->st_ino; - if (state->opt.force_by_name) { - /* check if the file path already exists */ - file = tommy_hashdyn_search(&disk->pathset, file_path_compare, sub, file_path_hash(sub)); - } else { - /* check if the file inode already exists */ - uint64_t inode = st->st_ino; - file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode)); - } - + /* first try finding by inode */ + file = tommy_hashdyn_search(&disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode)); if (file) { - /* check if multiple files have the same inode */ - if (file_flag_has(file, FILE_IS_PRESENT)) { - if (st->st_nlink > 1) { - /* it's a hardlink */ - scan_link(scan, state, output, disk, sub, file->sub, FILE_IS_HARDLINK); - return; - } else { - fprintf(stderr, "Internal inode '%"PRIu64"' inconsistency for file '%s%s'\n", (uint64_t)st->st_ino, disk->dir, sub); - exit(EXIT_FAILURE); - } - } - /* check if the file is not changed */ if (file->size == st->st_size && file->mtime_sec == st->st_mtime - /* always accept the value if it's STAT_NSEC_INVALID */ - /* it happens when upgrading from an old version of SnapRAID */ - && (file->mtime_nsec == STAT_NSEC(st) || file->mtime_nsec == STAT_NSEC_INVALID) + && (file->mtime_nsec == STAT_NSEC(st) + /* always accept the stored value if it's STAT_NSEC_INVALID */ + /* it happens when upgrading from an old version of SnapRAID */ + /* not yet supporting the nanosecond field */ + || file->mtime_nsec == STAT_NSEC_INVALID + ) ) { + /* check if multiple files have the same inode */ + if (file_flag_has(file, FILE_IS_PRESENT)) { + if (st->st_nlink > 1) { + /* it's a hardlink */ + scan_link(scan, state, output, disk, sub, file->sub, FILE_IS_HARDLINK); + return; + } else { + fprintf(stderr, "Internal inode '%"PRIu64"' inconsistency for file '%s%s' already present\n", (uint64_t)st->st_ino, disk->dir, sub); + exit(EXIT_FAILURE); + } + } + /* mark as present */ file_flag_set(file, FILE_IS_PRESENT); - /* update the nano seconds mtime if required */ + /* update the nano seconds mtime only if different */ + /* to avoid unneeded updates */ if (file->mtime_nsec == STAT_NSEC_INVALID && STAT_NSEC(st) != STAT_NSEC_INVALID ) { @@ -318,12 +319,7 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, if (strcmp(file->sub, sub) != 0) { /* if the path is different, it means a moved file with the same inode */ - ++scan->count_moved; - - if (file->inode != st->st_ino) { - fprintf(stderr, "Internal inode inconsistency for file '%s%s'\n", disk->dir, sub); - exit(EXIT_FAILURE); - } + ++scan->count_move; if (state->opt.gui) { fprintf(stdlog, "scan:move:%s:%s:%s\n", disk->name, file->sub, sub); @@ -333,41 +329,17 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, printf("Move '%s%s' '%s%s'\n", disk->dir, file->sub, disk->dir, sub); } - /* remove from the set */ + /* remove from the name set */ tommy_hashdyn_remove_existing(&disk->pathset, &file->pathset); /* save the new name */ file_rename(file, sub); - /* reinsert in the set */ + /* reinsert in the name set */ tommy_hashdyn_insert(&disk->pathset, &file->pathset, file, file_path_hash(file->sub)); /* we have to save the new name */ state->need_write = 1; - } else if (file->inode != st->st_ino) { - /* if the inode is different, it means a rewritten file with the same path */ - /* like when restoring a backup that restores also the time information */ - ++scan->count_moved; - - if (state->opt.gui) { - fprintf(stdlog, "scan:restore:%s:%s\n", disk->name, sub); - fflush(stdlog); - } - if (output) { - printf("Restore '%s%s'\n", disk->dir, sub); - } - - /* remove from the set */ - tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); - - /* save the new inode */ - file->inode = st->st_ino; - - /* reinsert in the set */ - tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); - - /* we have to save the new inode */ - state->need_write = 1; } else { /* otherwise it's equal */ ++scan->count_equal; @@ -380,59 +352,141 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state, /* nothing more to do */ return; - } else { - /* here if the file is changed */ - - /* do a safety check to ensure that the common ext4 case of zeroing */ - /* the size of a file after a crash doesn't propagate to the backup */ - if (file->size != 0 && st->st_size == 0) { - /* do the check ONLY if the name is the same */ - /* otherwise it could be a deleted and recreated file */ - if (strcmp(file->sub, sub) == 0) { - if (!state->opt.force_zero) { - fprintf(stderr, "The file '%s%s' has unexpected zero size! If this an expected state\n", disk->dir, sub); - fprintf(stderr, "you can '%s' anyway usinge 'snapraid --force-zero %s'\n", state->command, state->command); - fprintf(stderr, "Instead, it's possible that after a kernel crash this file was lost,\n"); - fprintf(stderr, "and you can use 'snapraid --filter %s fix' to recover it.\n", sub); - exit(EXIT_FAILURE); - } - } - } - - if (strcmp(file->sub, sub) == 0) { - /* if the name is the same, it's an update */ - if (state->opt.gui) { - fprintf(stdlog, "scan:update:%s:%s\n", disk->name, file->sub); - fflush(stdlog); - } - if (output) { - printf("Update '%s%s'\n", disk->dir, file->sub); - } - - ++scan->count_change; - } else { - /* if the name is different, it's an inode reuse */ - if (state->opt.gui) { - fprintf(stdlog, "scan:remove:%s:%s\n", disk->name, file->sub); - fprintf(stdlog, "scan:add:%s:%s\n", disk->name, sub); - fflush(stdlog); - } - if (output) { - printf("Remove '%s%s'\n", disk->dir, file->sub); - printf("Add '%s%s'\n", disk->dir, sub); - } - - ++scan->count_remove; - ++scan->count_insert; - } - - /* remove it */ - scan_file_remove(state, disk, file); - - /* and continue to reinsert it */ } + + /* here the file matches the inode, but not the other info */ + /* if could be a modified file with the same name, */ + /* or a restored/copied file that get assigned a previously used inode, */ + /* or a filesystem with not persistent inodes */ + + /* for sure it cannot be already present */ + if (file_flag_has(file, FILE_IS_PRESENT)) { + fprintf(stderr, "Internal inode '%"PRIu64"' inconsistency for files '%s%s' and '%s%s' matching already present but different\n", file->inode, disk->dir, sub, disk->dir, file->sub); + exit(EXIT_FAILURE); + } + + /* assume a previously used inode, it's the worst case */ + /* and we handle it removing the duplicate inode stored. */ + /* If the file is found by name (not necessarely in this function call), */ + /* it will have the inode info restored, otherwise, it will get removed */ + + /* remove from the inode set */ + tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); + + /* mark as missing inode */ + file_flag_set(file, FILE_IS_WITHOUT_INODE); + + /* go further to find it by name */ + } + + /* then try findind it by name */ + file = tommy_hashdyn_search(&disk->pathset, file_path_compare, sub, file_path_hash(sub)); + if (file) { + /* if the file is without an inode */ + if (file_flag_has(file, FILE_IS_WITHOUT_INODE)) { + /* set it now */ + file->inode = st->st_ino; + + /* insert in the set */ + tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + + /* unmark as missing inode */ + file_flag_clear(file, FILE_IS_WITHOUT_INODE); + } else { + /* here the inode has to be different, otherwise we would have found it before */ + if (file->inode == st->st_ino) { + fprintf(stderr, "Internal inode '%"PRIu64"' inconsistency for files '%s%s' as unexpected matching\n", file->inode, disk->dir, sub); + + exit(EXIT_FAILURE); + } + } + + /* for sure it cannot be already present */ + if (file_flag_has(file, FILE_IS_PRESENT)) { + fprintf(stderr, "Internal path inconsistency for file '%s%s' matching and already present\n", disk->dir, sub); + exit(EXIT_FAILURE); + } + + /* check if the file is not changed */ + if (file->size == st->st_size + && file->mtime_sec == st->st_mtime + && (file->mtime_nsec == STAT_NSEC(st) + /* always accept the stored value if it's STAT_NSEC_INVALID */ + /* it happens when upgrading from an old version of SnapRAID */ + /* not yet supporting the nanosecond field */ + || file->mtime_nsec == STAT_NSEC_INVALID + ) + ) { + /* here we know that the inode is different and it needs to be updated */ + /* otherwise we would have processed the file when finding by inode */ + state->need_write = 1; + + /* mark as present */ + file_flag_set(file, FILE_IS_PRESENT); + + /* always update the nano seconds mtime */ + /* to manage the above STAT_NSEC_INVALID case */ + file->mtime_nsec = STAT_NSEC(st); + + /* if the inode is different, it means a rewritten file with the same path */ + /* like when restoring a backup that restores also the time information */ + ++scan->count_restore; + + if (state->opt.gui) { + fprintf(stdlog, "scan:restore:%s:%s\n", disk->name, sub); + fflush(stdlog); + } + if (output) { + printf("Restore '%s%s'\n", disk->dir, sub); + } + + /* remove from the inode set */ + tommy_hashdyn_remove_existing(&disk->inodeset, &file->nodeset); + + /* save the new inode */ + file->inode = st->st_ino; + + /* reinsert in the inode set */ + tommy_hashdyn_insert(&disk->inodeset, &file->nodeset, file, file_inode_hash(file->inode)); + + /* nothing more to do */ + return; + } + + /* here if the file is changed but with the correct name */ + + /* do a safety check to ensure that the common ext4 case of zeroing */ + /* the size of a file after a crash doesn't propagate to the backup */ + if (file->size != 0 && st->st_size == 0) { + if (!state->opt.force_zero) { + fprintf(stderr, "The file '%s%s' has unexpected zero size! If this an expected state\n", disk->dir, sub); + fprintf(stderr, "you can '%s' anyway usinge 'snapraid --force-zero %s'\n", state->command, state->command); + fprintf(stderr, "Instead, it's possible that after a kernel crash this file was lost,\n"); + fprintf(stderr, "and you can use 'snapraid --filter %s fix' to recover it.\n", sub); + exit(EXIT_FAILURE); + } + } + + /* it has the same name, so it's an update */ + ++scan->count_change; + + if (state->opt.gui) { + fprintf(stdlog, "scan:update:%s:%s\n", disk->name, file->sub); + fflush(stdlog); + } + if (output) { + if (file->size != st->st_size) + printf("Update '%s%s' new size\n", disk->dir, file->sub); + else + printf("Update '%s%s' new modification time\n", disk->dir, file->sub); + } + + /* remove it */ + scan_file_remove(state, disk, file); + + /* and continue to reinsert it */ } else { - /* create the new file */ + /* if the name doesn't exist, it's a new file */ ++scan->count_insert; if (state->opt.gui) { @@ -735,7 +789,8 @@ void state_scan(struct snapraid_state* state, int output) scan = malloc_nofail(sizeof(struct snapraid_scan)); scan->count_equal = 0; - scan->count_moved = 0; + scan->count_move = 0; + scan->count_restore = 0; scan->count_change = 0; scan->count_remove = 0; scan->count_insert = 0; @@ -882,7 +937,7 @@ void state_scan(struct snapraid_state* state, int output) struct snapraid_disk* disk = i->data; struct snapraid_scan* scan = j->data; - if (scan->count_equal == 0 && scan->count_moved == 0 && scan->count_remove != 0) { + if (scan->count_equal == 0 && scan->count_move == 0 && scan->count_restore == 0 && (scan->count_remove != 0 || scan->count_change != 0)) { if (!has_empty) { has_empty = 1; fprintf(stderr, "All the files previously present in disk '%s' at dir '%s'", disk->name, disk->dir); @@ -893,10 +948,10 @@ void state_scan(struct snapraid_state* state, int output) } if (has_empty) { fprintf(stderr, " are now missing or rewritten!\n"); - fprintf(stderr, "This happens when deleting all the files from a disk,\n"); - fprintf(stderr, "or when all the files are recreated after a 'fix' command,\n"); - fprintf(stderr, "or manually copied. If this is really what you are doing, \n"); - fprintf(stderr, "you can '%s' anyway, using 'snapraid --force-empty %s'.\n", state->command, state->command); + fprintf(stderr, "This could happen when deleting all the files from a disk,\n"); + fprintf(stderr, "and restoring them with a program not setting correctly the timestamps.\n"); + fprintf(stderr, "If this is really what you are doing, you can '%s' anyway, \n", state->command); + fprintf(stderr, "using 'snapraid --force-empty %s'.\n", state->command); fprintf(stderr, "Instead, it's possible that you have some disks not mounted.\n"); exit(EXIT_FAILURE); } @@ -906,7 +961,8 @@ void state_scan(struct snapraid_state* state, int output) struct snapraid_scan total; total.count_equal = 0; - total.count_moved = 0; + total.count_move = 0; + total.count_restore = 0; total.count_change = 0; total.count_remove = 0; total.count_insert = 0; @@ -914,7 +970,8 @@ void state_scan(struct snapraid_state* state, int output) for(i=scanlist;i!=0;i=i->next) { struct snapraid_scan* scan = i->data; total.count_equal += scan->count_equal; - total.count_moved += scan->count_moved; + total.count_move += scan->count_move; + total.count_restore += scan->count_restore; total.count_change += scan->count_change; total.count_remove += scan->count_remove; total.count_insert += scan->count_insert; @@ -922,14 +979,15 @@ void state_scan(struct snapraid_state* state, int output) if (state->opt.verbose) { printf("\tequal %d\n", total.count_equal); - printf("\tmoved %d\n", total.count_moved); + printf("\tmoved %d\n", total.count_move); + printf("\trestored %d\n", total.count_restore); printf("\tchanged %d\n", total.count_change); printf("\tremoved %d\n", total.count_remove); printf("\tadded %d\n", total.count_insert); } if (output) { - if (!total.count_moved && !total.count_change && !total.count_remove && !total.count_insert) { + if (!total.count_move && !total.count_restore && !total.count_change && !total.count_remove && !total.count_insert) { printf("No difference.\n"); } } diff --git a/snapraid.1 b/snapraid.1 index 0d5399e4..f5cd3235 100644 --- a/snapraid.1 +++ b/snapraid.1 @@ -21,10 +21,6 @@ snapraid [\(hyc, \(hy\(hyconf CONFIG] [\(hyp, \(hy\(hypercentage PERC] [\(hyo, \(hy\(hyolder\(hythan DAYS] .PD 0 .PP -.PD - [\(hyN, \(hy\(hyfind\(hyby\(hyname] -.PD 0 -.PP .PD [\(hyZ, \(hy\(hyforce\(hyzero] [\(hyE, \(hy\(hyforce\(hyempty] .PD 0 @@ -627,20 +623,6 @@ The files are read also in subdirectories and they are identified regardless of their name. This option can be used only with the \(a"check\(a" and \(a"fix\(a" command. .TP -.B \(hyN, \(hy\(hyfind\(hyby\(hyname -When syncing finds the files by path instead than by inode, -and ignores the nanosecond part of timestamp. -This option allows a fast sync command after having replaced -one physical disk with another, copying manually the files. -Without this option the \(a"sync\(a" command recognizes that -the files were copied to a different disk, and it will resync -them all. With this option, a file with the correct path, -size and time with second precision is assumed identical at -the previous one, and not resynched. -The nanosecond part of timestamps is ignored because most of -copy programs are not able to correctly restore it. -This option can be used only with the \(a"sync\(a" and \(a"diff\(a" commands. -.TP .B \(hyZ, \(hy\(hyforce\(hyzero Forces the insecure operation of syncing a file with zero size that before was not. @@ -1138,12 +1120,8 @@ This command will take a long time. .SS STEP 4 \(hy> Sync Run the \(a"sync\(a" command to resyncronize the array with the new disk. .PP -To avoid a long time sync you can use the \(a"\(hy\(hyfind\(hyby\(hyname\(a" option to -force SnapRAID to ignore the fact that all the recovered files are now in -a different physical disk, but they are not changed. -.PP .RS 4 -snapraid \(hy\(hyfind\(hyby\(hyname sync +snapraid sync .PD 0 .PP .PD diff --git a/snapraid.c b/snapraid.c index a54a6371..e3aa6faa 100644 --- a/snapraid.c +++ b/snapraid.c @@ -68,7 +68,6 @@ void usage(void) printf(" " SWITCH_GETOPT_LONG("-i, --import DIR ", "-i") " Import deleted files\n"); printf(" " SWITCH_GETOPT_LONG("-l, --log FILE ", "-l") " Log file. Default none\n"); printf(" " SWITCH_GETOPT_LONG("-a, --audit-only ", "-A") " Check only file data and not parity\n"); - printf(" " SWITCH_GETOPT_LONG("-N, --find-by-name ", "-N") " Find the files by name instead than by inode\n"); printf(" " SWITCH_GETOPT_LONG("-Z, --force-zero ", "-Z") " Force synching of files that get zero size\n"); printf(" " SWITCH_GETOPT_LONG("-E, --force-empty ", "-E") " Force synching of disks that get empty\n"); printf(" " SWITCH_GETOPT_LONG("-U, --force-uuid ", "-U") " Force commands on disks with uuid changed\n"); @@ -117,7 +116,7 @@ struct option long_options[] = { { "force-empty", 0, 0, 'E' }, { "force-uuid", 0, 0, 'U' }, { "force-device", 0, 0, 'D' }, - { "find-by-name", 0, 0, 'N' }, + { "find-by-name", 0, 0, 'N' }, /* deprecated in SnapRAID 4.0 */ { "audit-only", 0, 0, 'a' }, { "speed-test", 0, 0, 'T' }, { "verbose", 0, 0, 'v' }, @@ -337,7 +336,7 @@ int main(int argc, char* argv[]) opt.force_device = 1; break; case 'N' : - opt.force_by_name = 1; + fprintf(stderr, "warning: Option --find-by-name, -N is deprecated and does nothing!\n"); break; case 'a' : audit_only = 1; @@ -464,17 +463,6 @@ int main(int argc, char* argv[]) } } - switch (operation) { - case OPERATION_SYNC : - case OPERATION_DIFF : - break; - default: - if (opt.force_by_name) { - fprintf(stderr, "You cannot use -N, --find-by-name with the '%s' command\n", command); - exit(EXIT_FAILURE); - } - } - switch (operation) { case OPERATION_CHECK : case OPERATION_FIX : diff --git a/snapraid.d b/snapraid.d index 1b758de3..5f978631 100644 --- a/snapraid.d +++ b/snapraid.d @@ -7,7 +7,6 @@ Synopsis : [-m, --filter-missing] [-e, --filter-error] : [-a, --audit-only] [-i, --import DIR] : [-p, --percentage PERC] [-o, --older-than DAYS] - : [-N, --find-by-name] : [-Z, --force-zero] [-E, --force-empty] : [-U, --force-uuid] [-D, --force-device] : [-s, --start BLKSTART] [-t, --count BLKCOUNT] @@ -448,20 +447,6 @@ Options identified regardless of their name. This option can be used only with the "check" and "fix" command. - -N, --find-by-name - When syncing finds the files by path instead than by inode, - and ignores the nanosecond part of timestamp. - This option allows a fast sync command after having replaced - one physical disk with another, copying manually the files. - Without this option the "sync" command recognizes that - the files were copied to a different disk, and it will resync - them all. With this option, a file with the correct path, - size and time with second precision is assumed identical at - the previous one, and not resynched. - The nanosecond part of timestamps is ignored because most of - copy programs are not able to correctly restore it. - This option can be used only with the "sync" and "diff" commands. - -Z, --force-zero Forces the insecure operation of syncing a file with zero size that before was not. @@ -827,11 +812,7 @@ Recovering STEP 4 -> Sync Run the "sync" command to resyncronize the array with the new disk. - To avoid a long time sync you can use the "--find-by-name" option to - force SnapRAID to ignore the fact that all the recovered files are now in - a different physical disk, but they are not changed. - - :snapraid --find-by-name sync + :snapraid sync If everything was recovered, this command is immediate. diff --git a/snapraid.txt b/snapraid.txt index 333fb760..81943a28 100644 --- a/snapraid.txt +++ b/snapraid.txt @@ -11,7 +11,6 @@ snapraid [-c, --conf CONFIG] [-m, --filter-missing] [-e, --filter-error] [-a, --audit-only] [-i, --import DIR] [-p, --percentage PERC] [-o, --older-than DAYS] - [-N, --find-by-name] [-Z, --force-zero] [-E, --force-empty] [-U, --force-uuid] [-D, --force-device] [-s, --start BLKSTART] [-t, --count BLKCOUNT] @@ -491,20 +490,6 @@ SnapRAID provides the following options: identified regardless of their name. This option can be used only with the "check" and "fix" command. - -N, --find-by-name - When syncing finds the files by path instead than by inode, - and ignores the nanosecond part of timestamp. - This option allows a fast sync command after having replaced - one physical disk with another, copying manually the files. - Without this option the "sync" command recognizes that - the files were copied to a different disk, and it will resync - them all. With this option, a file with the correct path, - size and time with second precision is assumed identical at - the previous one, and not resynched. - The nanosecond part of timestamps is ignored because most of - copy programs are not able to correctly restore it. - This option can be used only with the "sync" and "diff" commands. - -Z, --force-zero Forces the insecure operation of syncing a file with zero size that before was not. @@ -903,11 +888,7 @@ This command will take a long time. Run the "sync" command to resyncronize the array with the new disk. -To avoid a long time sync you can use the "--find-by-name" option to -force SnapRAID to ignore the fact that all the recovered files are now in -a different physical disk, but they are not changed. - - snapraid --find-by-name sync + snapraid sync If everything was recovered, this command is immediate. diff --git a/state.c b/state.c index a470e1c1..a346bd97 100644 --- a/state.c +++ b/state.c @@ -1211,10 +1211,6 @@ static void state_read_text(struct snapraid_state* state, const char* path, STRE exit(EXIT_FAILURE); } - /* ignore nanoseconds if asked to find by name */ - if (state->opt.force_by_name) - v_mtime_nsec = STAT_NSEC_INVALID; - c = sgetc(f); } else { /* use a special value, meaning that we don't have this information */ @@ -2142,10 +2138,6 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST else --v_mtime_nsec; - /* ignore nanoseconds if asked to find by name */ - if (state->opt.force_by_name) - v_mtime_nsec = STAT_NSEC_INVALID; - ret = sgetb64(f, &v_inode); if (ret < 0) { decoding_error(path, f); @@ -3162,7 +3154,7 @@ void state_read(struct snapraid_state* state) exit(EXIT_FAILURE); } - /* go futher to check other content files */ + /* go further to check other content files */ while (node) { char other_path[PATH_MAX]; struct stat other_st; diff --git a/state.h b/state.h index 34eae6cd..802ee6cc 100644 --- a/state.h +++ b/state.h @@ -42,7 +42,6 @@ struct snapraid_option { int force_empty; /**< Forced dangerous operations of synching disks now empty. */ int force_uuid; /**< Forced dangerous operations of synching disks with uuid changed. */ int force_device; /**< Forced dangerous operations of using disks with save device id. */ - int force_by_name; /**< Forced dangerous operations of synching a rewritten disk. */ int expect_unrecoverable; /**< Expect presence of unrecoverable error in checking or fixing. */ int expect_recoverable; /**< Expect presence of recoverable error in checking. */ int skip_device; /**< Skip devices matching checks. */