Skip to content

Instantly share code, notes, and snippets.

@thread13
Last active April 8, 2017 14:33
Show Gist options
  • Save thread13/7db670f0b22ff9a984c8dca75b769f26 to your computer and use it in GitHub Desktop.
Save thread13/7db670f0b22ff9a984c8dca75b769f26 to your computer and use it in GitHub Desktop.
a proposed patch for rsync v. 3.1.1 to fix faulty nanosecond mtimes
diff -r 534ce1d4fb97 rsync.c
--- a/rsync.c Sat Apr 08 20:56:59 2017 +1000
+++ b/rsync.c Sat Apr 08 21:02:00 2017 +1000
@@ -549,7 +549,21 @@
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) ;
+ /* warnings / debug */
+ if ( ns < 0 ) {
+ rprintf(FWARNING, "negative ns mtime (%ld) on %s\n",
+ ns, full_fname(fname));
+ } else if ( ns >= NS_MAX ) {
+ if (DEBUG_GTE(TIME, 1)) {
+ rprintf(FWARNING, "ns mtime >= 1 sec (%ld) on %s\n",
+ ns, full_fname(fname));
+ }
+ }
+ /* do an explicit conversion before set_modtime() does an implicit one */
+ ns = ZERO_IF_NEG(ns);
+ 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 534ce1d4fb97 rsync.h
--- a/rsync.h Sat Apr 08 20:56:59 2017 +1000
+++ b/rsync.h Sat Apr 08 21:02:00 2017 +1000
@@ -737,6 +737,10 @@
#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 NS_MAX 1000000000 /* nb: fits in int32 */
/* 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