diff --git a/check.c b/check.c index 33b86bc7..2bd76db4 100644 --- a/check.c +++ b/check.c @@ -1034,7 +1034,7 @@ static int state_check_process(struct snapraid_state* state, int check, int fix, collide_file = tommy_hashdyn_search(&handle[j].disk->inodeset, file_inode_compare_to_arg, &inode, file_inode_hash(inode)); /* if the inode is already in the database and it refers at a different file name, */ - /* we can fix the file time ONLY if the time and size allow to differentiates */ + /* we can fix the file time ONLY if the time and size allow to differentiate */ /* between the two files */ /* for example, suppose we delete a bunch of files with all the same size and time, */ @@ -1045,7 +1045,7 @@ static int state_check_process(struct snapraid_state* state, int check, int fix, || strcmp(collide_file->sub, file->sub) == 0 /* if the name is the same, it's the right collision */ || collide_file->size != file->size /* if the size is different, the collision is identified */ || collide_file->mtime_sec != file->mtime_sec /* if the mtime is different, the collision is identified */ - || collide_file->mtime_nsec != file->mtime_nsec + || collide_file->mtime_nsec != file->mtime_nsec /* same for mtime_nsec */ ) { /* set the original modification time */ ret = handle_utime(&handle[j]); @@ -1121,7 +1121,7 @@ close_and_continue: if (!handle[i].disk) continue; - /* for each file in the disk */ + /* for each empty file in the disk */ disk = handle[i].disk; node = disk->filelist; while (node) { @@ -1192,8 +1192,25 @@ close_and_continue: goto bail; } + /* set the original modification time */ + ret = file_utime(file, f); + if (ret != 0) { + close(f); + + fprintf(stderr, "WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + printf("Stopping\n"); + ++unrecoverable_error; + goto bail; + } + /* close it */ - close(f); + ret = close(f); + if (ret != 0) { + fprintf(stderr, "WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); + printf("Stopping\n"); + ++unrecoverable_error; + goto bail; + } fprintf(stdlog, "fixed:%s:%s: Fixed empty file\n", disk->name, file->sub); ++recovered_error; diff --git a/handle.c b/handle.c index bf41f34c..1b22474b 100644 --- a/handle.c +++ b/handle.c @@ -318,7 +318,7 @@ int handle_write(struct snapraid_handle* handle, struct snapraid_block* block, u return 0; } -int handle_utime(struct snapraid_handle* handle) +int file_utime(struct snapraid_file* file, int f) { #if HAVE_FUTIMENS struct timespec tv[2]; @@ -327,52 +327,57 @@ int handle_utime(struct snapraid_handle* handle) #endif int ret; - /* do nothing if not opened */ - if (handle->f == -1) - return 0; - #if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */ - tv[0].tv_sec = handle->file->mtime_sec; - if (handle->file->mtime_nsec != STAT_NSEC_INVALID) - tv[0].tv_nsec = handle->file->mtime_nsec; + tv[0].tv_sec = file->mtime_sec; + if (file->mtime_nsec != STAT_NSEC_INVALID) + tv[0].tv_nsec = file->mtime_nsec; else tv[0].tv_nsec = 0; tv[1].tv_sec = tv[0].tv_sec; tv[1].tv_nsec = tv[0].tv_nsec; - ret = futimens(handle->f, tv); + ret = futimens(f, tv); #elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */ - tv[0].tv_sec = handle->file->mtime_sec; - if (handle->file->mtime_nsec != STAT_NSEC_INVALID) - tv[0].tv_usec = handle->file->mtime_nsec / 1000; + tv[0].tv_sec = file->mtime_sec; + if (file->mtime_nsec != STAT_NSEC_INVALID) + tv[0].tv_usec = file->mtime_nsec / 1000; else tv[0].tv_usec = 0; tv[1].tv_sec = tv[0].tv_sec; tv[1].tv_usec = tv[0].tv_usec; - ret = futimes(handle->f, tv); + ret = futimes(f, tv); #elif HAVE_FUTIMESAT /* fallback to futimesat() for Solaris, it only has futimesat() */ - tv[0].tv_sec = handle->file->mtime_sec; - if (handle->file->mtime_nsec != STAT_NSEC_INVALID) - tv[0].tv_usec = handle->file->mtime_nsec / 1000; + tv[0].tv_sec = file->mtime_sec; + if (file->mtime_nsec != STAT_NSEC_INVALID) + tv[0].tv_usec = file->mtime_nsec / 1000; else tv[0].tv_usec = 0; tv[1].tv_sec = tv[0].tv_sec; tv[1].tv_usec = tv[0].tv_usec; - ret = futimesat(handle->f, 0, tv); + ret = futimesat(f, 0, tv); #else #error No function available to set file timestamps #endif if (ret != 0) { - fprintf(stderr, "Error timing file '%s'. %s.\n", handle->file->sub, strerror(errno)); + fprintf(stderr, "Error timing file '%s'. %s.\n", file->sub, strerror(errno)); return -1; } return 0; } +int handle_utime(struct snapraid_handle* handle) +{ + /* do nothing if not opened */ + if (handle->f == -1) + return 0; + + return file_utime(handle->file, handle->f); +} + struct snapraid_handle* handle_map(struct snapraid_state* state, unsigned* handlemax) { tommy_node* i; diff --git a/handle.h b/handle.h index 733f7f9c..9c69b6d9 100644 --- a/handle.h +++ b/handle.h @@ -20,6 +20,14 @@ #include "state.h" +/****************************************************************************/ +/* file */ + +/** + * Changes the modification time of a open file to the saved value. + */ +int file_utime(struct snapraid_file* file, int f); + /****************************************************************************/ /* handle */