Removes 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
This commit is contained in:
Andrea Mazzoleni 2013-08-26 20:33:25 +02:00
parent 3a5ce4e522
commit 8eafeafcb6
11 changed files with 204 additions and 227 deletions

View file

@ -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.

View file

@ -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*

10
TODO
View file

@ -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".

9
elem.h
View file

@ -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.
*/

306
scan.c
View file

@ -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");
}
}

View file

@ -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

View file

@ -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 :

View file

@ -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.

View file

@ -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.

10
state.c
View file

@ -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;

View file

@ -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. */