Created
April 8, 2017 14:36
-
-
Save thread13/a3607257dd23f908354d650fa9446501 to your computer and use it in GitHub Desktop.
a proposed patch for rsync v. 3.1.1 to fix faulty nanosecond mtimes -- ignoring 1 second overflow as well ( at least Linux futimens() wants that )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r 27d7a363f071 rsync.c | |
--- a/rsync.c Sat Apr 08 21:05:18 2017 +1000 | |
+++ b/rsync.c Sat Apr 08 23:04:43 2017 +1000 | |
@@ -549,7 +549,29 @@ | |
flags |= ATTRS_SKIP_MTIME; | |
if (!(flags & ATTRS_SKIP_MTIME) | |
&& cmp_time(sxp->st.st_mtime, file->modtime) != 0) { | |
- int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode); | |
+ | |
+ /* tv_nsec is a long type */ | |
+ long ns = F_MOD_NSEC(file) ; | |
+ /* check and complain */ | |
+ if ( ns < 0 ) { | |
+ rprintf(FWARNING, "warning: negative ns mtime (%ld) on %s\n", | |
+ ns, full_fname(fname)); | |
+ } else if ( ns >= NSEC_MAX ) { | |
+ rprintf(FWARNING, "warning: ns mtime >= 1 sec (%ld) on %s\n", | |
+ ns, full_fname(fname)); | |
+ } | |
+ /* Ok, now let's fix it */ | |
+ if ( NSEC_UNEXPECTED(ns) ) { | |
+ if (DEBUG_GTE(TIME, 1)) { | |
+ rprintf(FINFO, "! changing nsec time (%ld) to 0 on %s\n", | |
+ ns, full_fname(fname)); | |
+ } | |
+ | |
+ /* for negative values, that would also avoid implicit conversions */ | |
+ ns = 0 ; | |
+ } | |
+ | |
+ int ret = set_modtime(fname, file->modtime, ns, sxp->st.st_mode); | |
if (ret < 0) { | |
rsyserr(FERROR_XFER, errno, "failed to set times on %s", | |
full_fname(fname)); | |
diff -r 27d7a363f071 rsync.h | |
--- a/rsync.h Sat Apr 08 21:05:18 2017 +1000 | |
+++ b/rsync.h Sat Apr 08 23:04:43 2017 +1000 | |
@@ -737,6 +737,11 @@ | |
#endif | |
#define F_MOD_NSEC(f) ((f)->flags & FLAG_MOD_NSEC ? OPT_EXTRA(f, 0)->unum : 0) | |
+/* since we use unsigned ns, and since they are not supposed to be negative: */ | |
+#define ZERO_IF_NEG(ns) ( ((ns) < 0) ? 0 : (ns) ) | |
+/* ns tail is expected to be < 10^9 */ | |
+#define NSEC_MAX 1000000000 /* nb: fits in int32 */ | |
+#define NSEC_UNEXPECTED(ns) ( ((ns) < 0) || (ns) >= NSEC_MAX ) | |
/* If there is a symlink string, it is always right after the basename */ | |
#define F_SYMLINK(f) ((f)->basename + strlen((f)->basename) + 1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment