The Samba-Bugzilla – Attachment 12556 Details for
Bug 11588
better handling for --preallocate with --sparse
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Preliminary patch to support punching holes
sparse.diff (text/plain), 5.81 KB, created by
Wayne Davison
on 2016-10-08 18:18:13 UTC
(
hide
)
Description:
Preliminary patch to support punching holes
Filename:
MIME Type:
Creator:
Wayne Davison
Created:
2016-10-08 18:18:13 UTC
Size:
5.81 KB
patch
obsolete
>diff --git a/configure.ac b/configure.ac >index b5e4049..e01e124 100644 >--- a/configure.ac >+++ b/configure.ac >@@ -614,6 +614,36 @@ if test x"$rsync_cv_have_fallocate" = x"yes"; then > AC_DEFINE(HAVE_FALLOCATE, 1, [Define to 1 if you have the fallocate function and it compiles and links without error]) > fi > >+AC_MSG_CHECKING([for FALLOC_FL_PUNCH_HOLE]) >+AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ >+ #define _GNU_SOURCE 1 >+ #include <linux/falloc.h> >+ #ifndef FALLOC_FL_PUNCH_HOLE >+ #error FALLOC_FL_PUNCH_HOLE is missing >+ #endif >+ ]])], [ >+ AC_MSG_RESULT([yes]) >+ AC_DEFINE([HAVE_FALLOC_FL_PUNCH_HOLE], [1], [Define if FALLOC_FL_PUNCH_HOLE is available.]) >+ ], [ >+ AC_MSG_RESULT([no]) >+ ] >+) >+ >+AC_MSG_CHECKING([for FALLOC_FL_ZERO_RANGE]) >+AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ >+ #define _GNU_SOURCE 1 >+ #include <linux/falloc.h> >+ #ifndef FALLOC_FL_ZERO_RANGE >+ #error FALLOC_FL_ZERO_RANGE is missing >+ #endif >+ ]])], [ >+ AC_MSG_RESULT([yes]) >+ AC_DEFINE([HAVE_FALLOC_FL_ZERO_RANGE], [1], [Define if FALLOC_FL_ZERO_RANGE is available.]) >+ ], [ >+ AC_MSG_RESULT([no]) >+ ] >+) >+ > AC_CACHE_CHECK([for SYS_fallocate],rsync_cv_have_sys_fallocate,[ > AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/syscall.h> > #include <sys/types.h>]], [[syscall(SYS_fallocate, 0, 0, (loff_t)0, (loff_t)0);]])],[rsync_cv_have_sys_fallocate=yes],[rsync_cv_have_sys_fallocate=no])]) >diff --git a/fileio.c b/fileio.c >index 70e079d..7b9caf7 100644 >--- a/fileio.c >+++ b/fileio.c >@@ -34,8 +34,11 @@ > #define ALIGNED_LENGTH(len) ((((len) - 1) | (ALIGN_BOUNDRY-1)) + 1) > > extern int sparse_files; >+extern int inplace; >+extern int preallocate_files; > > static OFF_T sparse_seek = 0; >+static OFF_T sparse_last_write = 0; > > int sparse_end(int f, OFF_T size) > { >@@ -63,8 +66,9 @@ int sparse_end(int f, OFF_T size) > return ret; > } > >- >-static int write_sparse(int f, char *buf, int len) >+/* Note that the offset is just the caller letting us know where >+ * the current file position is in the file. */ >+static int write_sparse(int f, OFF_T offset, const char *buf, int len) > { > int l1 = 0, l2 = 0; > int ret; >@@ -77,9 +81,14 @@ static int write_sparse(int f, char *buf, int len) > if (l1 == len) > return len; > >- if (sparse_seek) >- do_lseek(f, sparse_seek, SEEK_CUR); >+ if (sparse_seek) { >+ if (!inplace && !preallocate_files) >+ do_lseek(f, sparse_seek, SEEK_CUR); >+ else if (do_punch_hole(f, sparse_last_write, sparse_seek) < 0) >+ return -1; >+ } > sparse_seek = l2; >+ sparse_last_write = offset + len - l2; > > while ((ret = write(f, buf + l1, len - (l1+l2))) <= 0) { > if (ret < 0 && errno == EINTR) >@@ -121,9 +130,11 @@ int flush_write_file(int f) > > /* > * write_file does not allow incomplete writes. It loops internally >- * until len bytes are written or errno is set. >+ * until len bytes are written or errno is set. Note that "offset" >+ * cannot be used to set a different location in the file -- it is >+ * just used to interface with write_sparse(). > */ >-int write_file(int f, char *buf, int len) >+int write_file(int f, OFF_T offset, char *buf, int len) > { > int ret = 0; > >@@ -131,7 +142,7 @@ int write_file(int f, char *buf, int len) > int r1; > if (sparse_files > 0) { > int len1 = MIN(len, SPARSE_WRITE_SIZE); >- r1 = write_sparse(f, buf, len1); >+ r1 = write_sparse(f, offset, buf, len1); > } else { > if (!wf_writeBuf) { > wf_writeBufSize = WRITE_SIZE * 8; >diff --git a/options.c b/options.c >index 308443b..85b1f08 100644 >--- a/options.c >+++ b/options.c >@@ -2237,13 +2237,15 @@ int parse_arguments(int *argc_p, const char ***argv_p) > bwlimit_writemax = 512; > } > >+#if !defined HAVE_FALLOCATE || !defined HAVE_FALLOC_FL_PUNCH_HOLE > if (sparse_files && inplace) { > /* Note: we don't check for this below, because --append is > * OK with --sparse (as long as redos are handled right). */ > snprintf(err_buf, sizeof err_buf, >- "--sparse cannot be used with --inplace\n"); >+ "This rsync cannot combine --sparse with --inplace\n"); > return 0; > } >+#endif > > if (append_mode) { > if (whole_file > 0) { >diff --git a/receiver.c b/receiver.c >index f9b97dd..d702603 100644 >--- a/receiver.c >+++ b/receiver.c >@@ -318,7 +318,7 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r, > > sum_update(data, i); > >- if (fd != -1 && write_file(fd,data,i) != i) >+ if (fd != -1 && write_file(fd, offset, data, i) != i) > goto report_write_error; > offset += i; > continue; >@@ -362,7 +362,7 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r, > continue; > } > } >- if (fd != -1 && map && write_file(fd, map, len) != (int)len) >+ if (fd != -1 && map && write_file(fd, offset, map, len) != (int)len) > goto report_write_error; > offset += len; > } >diff --git a/syscall.c b/syscall.c >index ecca2f1..ae5eeff 100644 >--- a/syscall.c >+++ b/syscall.c >@@ -444,6 +444,40 @@ int do_fallocate(int fd, OFF_T offset, OFF_T length) > } > #endif > >+/* NOTE: the offset must be the same as the current file position! */ >+int do_punch_hole(int fd, OFF_T offset, int len) >+{ >+#ifdef HAVE_FALLOCATE >+# ifdef HAVE_FALLOC_FL_PUNCH_HOLE >+ if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, len) == 0) { >+ do_lseek(fd, offset + len, SEEK_SET); >+ return 0; >+ } >+# endif >+# ifdef HAVE_FALLOC_FL_ZERO_RANGE >+ if (fallocate(fd, FALLOC_FL_ZERO_RANGE, offset, len) == 0) { >+ do_lseek(fd, offset + len, SEEK_SET); >+ return 0; >+ } >+# endif >+#endif >+ { >+ char zeros[4096]; >+ memset(zeros, 0, sizeof zeros); >+ while (len > 0) { >+ int chunk = len > (int)sizeof zeros ? (int)sizeof zeros : len; >+ int wrote = write(fd, zeros, chunk); >+ if (wrote <= 0) { >+ if (wrote < 0 && errno == EINTR) >+ continue; >+ return -1; >+ } >+ len -= wrote; >+ } >+ } >+ return 0; >+} >+ > int do_open_nofollow(const char *pathname, int flags) > { > #ifndef O_NOFOLLOW
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 11588
: 12556 |
12557