Applying the preallocate patch.
[rsync/rsync.git] / syscall.c
index aba0009..1ed36f3 100644 (file)
--- a/syscall.c
+++ b/syscall.c
 #include <sys/attr.h>
 #endif
 
+#if defined HAVE_SYS_FALLOCATE && !defined HAVE_FALLOCATE
+#include <sys/syscall.h>
+#endif
+
 extern int dry_run;
 extern int am_root;
 extern int am_sender;
@@ -226,6 +230,22 @@ int do_rename(const char *fname1, const char *fname2)
        return rename(fname1, fname2);
 }
 
+#ifdef HAVE_FTRUNCATE
+int do_ftruncate(int fd, OFF_T size)
+{
+       int ret;
+
+       if (dry_run) return 0;
+       RETURN_ERROR_IF_RO_OR_LO;
+
+       do {
+               ret = ftruncate(fd, size);
+       } while (ret < 0 && errno == EINTR);
+
+       return ret;
+}
+#endif
+
 void trim_trailing_slashes(char *name)
 {
        int l;
@@ -327,3 +347,99 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence)
        return lseek(fd, offset, whence);
 #endif
 }
+
+#ifdef HAVE_UTIMENSAT
+int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec)
+{
+       struct timespec t[2];
+
+       if (dry_run) return 0;
+       RETURN_ERROR_IF_RO_OR_LO;
+
+       t[0].tv_sec = 0;
+       t[0].tv_nsec = UTIME_NOW;
+       t[1].tv_sec = modtime;
+       t[1].tv_nsec = mod_nsec;
+       return utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW);
+}
+#endif
+
+#ifdef HAVE_LUTIMES
+int do_lutimes(const char *fname, time_t modtime, uint32 mod_nsec)
+{
+       struct timeval t[2];
+
+       if (dry_run) return 0;
+       RETURN_ERROR_IF_RO_OR_LO;
+
+       t[0].tv_sec = time(NULL);
+       t[0].tv_usec = 0;
+       t[1].tv_sec = modtime;
+       t[1].tv_usec = mod_nsec / 1000;
+       return lutimes(fname, t);
+}
+#endif
+
+#ifdef HAVE_UTIMES
+int do_utimes(const char *fname, time_t modtime, uint32 mod_nsec)
+{
+       struct timeval t[2];
+
+       if (dry_run) return 0;
+       RETURN_ERROR_IF_RO_OR_LO;
+
+       t[0].tv_sec = time(NULL);
+       t[0].tv_usec = 0;
+       t[1].tv_sec = modtime;
+       t[1].tv_usec = mod_nsec / 1000;
+       return utimes(fname, t);
+}
+
+#elif defined HAVE_UTIME
+int do_utime(const char *fname, time_t modtime, UNUSED(uint32 mod_nsec))
+{
+#ifdef HAVE_STRUCT_UTIMBUF
+       struct utimbuf tbuf;
+#else
+       time_t t[2];
+#endif
+
+       if (dry_run) return 0;
+       RETURN_ERROR_IF_RO_OR_LO;
+
+# ifdef HAVE_STRUCT_UTIMBUF
+       tbuf.actime = time(NULL);
+       tbuf.modtime = modtime;
+       return utime(fname, &tbuf);
+# else
+       t[0] = time(NULL);
+       t[1] = modtime;
+       return utime(fname, t);
+# endif
+}
+
+#else
+#error Need utimes or utime function.
+#endif
+
+#ifdef SUPPORT_PREALLOCATION
+int do_fallocate(int fd, OFF_T offset, OFF_T length)
+{
+#ifdef FALLOC_FL_KEEP_SIZE
+#define DO_FALLOC_OPTIONS FALLOC_FL_KEEP_SIZE
+#else
+#define DO_FALLOC_OPTIONS 0
+#endif
+       RETURN_ERROR_IF(dry_run, 0);
+       RETURN_ERROR_IF_RO_OR_LO;
+#if defined HAVE_FALLOCATE
+       return fallocate(fd, DO_FALLOC_OPTIONS, offset, length);
+#elif defined HAVE_SYS_FALLOCATE
+       return syscall(SYS_fallocate, fd, DO_FALLOC_OPTIONS, (loff_t)offset, (loff_t)length);
+#elif defined HAVE_EFFICIENT_POSIX_FALLOCATE
+       return posix_fallocate(fd, offset, length);
+#else
+#error Coding error in SUPPORT_PREALLOCATION logic.
+#endif
+}
+#endif