Added a flag to disable xattr hlink optimization.
authorWayne Davison <wayned@samba.org>
Sun, 8 Jun 2014 17:22:09 +0000 (10:22 -0700)
committerWayne Davison <wayned@samba.org>
Sun, 8 Jun 2014 17:42:14 +0000 (10:42 -0700)
I added a compatibility flag for protocol 31 that will let both sides
know if they should be using the xattr optimization that attempted to
avoid sending xattr info for hardlinked files.  Since this optimization
was causing some issues, this compatibility flag will ensure that both
sides know if they should be trying to use the optimization or not.

NEWS
compat.c
generator.c
options.c
receiver.c
sender.c

diff --git a/NEWS b/NEWS
index 9e50fe0c1011367afa13178a292a68a6daabbcc0..22766ce668761267b726a32a4c61d0201d957d72 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -56,8 +56,8 @@ Changes since 3.1.0:
     - Improve chunked xattr reading for OS X.
 
     - Removed an attempted hard-link xattr optimization that was causing a
-      transfer failure.  (If you need to interact with an rsync 3.1.0 using
-      --hard-links & --xattrs, you can specify --protocol=30.)
+      transfer failure.  This removal is flagged in the compatibility code, so
+      if a better fix can be discovered, we have a way to flip it on again.
 
     - We now generate a better error if the buffer overflows in do_mknod().
 
index 23ed53a9947b6dc565db623beedb5bc4a8133ef7..2454937f85ff08ef298a31c20c7c756d8c26d6ad 100644 (file)
--- a/compat.c
+++ b/compat.c
@@ -26,6 +26,7 @@ int file_extra_cnt = 0; /* count of file-list extras that everyone gets */
 int inc_recurse = 0;
 int compat_flags = 0;
 int use_safe_inc_flist = 0;
+int want_xattr_optim = 0;
 
 extern int am_server;
 extern int am_sender;
@@ -76,6 +77,7 @@ int filesfrom_convert = 0;
 #define CF_SYMLINK_TIMES (1<<1)
 #define CF_SYMLINK_ICONV (1<<2)
 #define CF_SAFE_FLIST   (1<<3)
+#define CF_AVOID_XATTR_OPTIM (1<<4)
 
 static const char *client_info;
 
@@ -267,11 +269,14 @@ void setup_protocol(int f_out,int f_in)
 #endif
                        if (local_server || strchr(client_info, 'f') != NULL)
                                compat_flags |= CF_SAFE_FLIST;
+                       if (local_server || strchr(client_info, 'x') != NULL)
+                               compat_flags |= CF_AVOID_XATTR_OPTIM;
                        write_byte(f_out, compat_flags);
                } else
                        compat_flags = read_byte(f_in);
                /* The inc_recurse var MUST be set to 0 or 1. */
                inc_recurse = compat_flags & CF_INC_RECURSE ? 1 : 0;
+               want_xattr_optim = protocol_version >= 31 && !(compat_flags & CF_AVOID_XATTR_OPTIM);
                if (am_sender) {
                        receiver_symlink_times = am_server
                            ? strchr(client_info, 'L') != NULL
index 0f7a5169d49d12a4ad68140b65b2085488784b1b..63399d3d9a3cfd7fa699bc8bc47ce5510ef06563 100644 (file)
@@ -57,6 +57,7 @@ extern int update_only;
 extern int human_readable;
 extern int ignore_existing;
 extern int ignore_non_existing;
+extern int want_xattr_optim;
 extern int inplace;
 extern int append_mode;
 extern int make_backups;
@@ -553,7 +554,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
 #ifdef SUPPORT_XATTRS
                        if (preserve_xattrs && do_xfers
                         && iflags & (ITEM_REPORT_XATTR|ITEM_TRANSFER)) {
-                               int fd = iflags & ITEM_REPORT_XATTR ? sock_f_out : -1;
+                               int fd = iflags & ITEM_REPORT_XATTR
+                                     && !(want_xattr_optim && BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))
+                                      ? sock_f_out : -1;
                                send_xattr_request(NULL, file, fd);
                        }
 #endif
index 0aa64bf0f845a9a291d35da674eabc71d5de6091..5b061ade10d2de92777e78e99488d7904d038be7 100644 (file)
--- a/options.c
+++ b/options.c
@@ -2494,12 +2494,13 @@ void server_options(char **args, int *argc_p)
                if (allow_inc_recurse)
                        argstr[x++] = 'i';
 #ifdef CAN_SET_SYMLINK_TIMES
-               argstr[x++] = 'L';
+               argstr[x++] = 'L'; /* symlink time-setting support */
 #endif
 #ifdef ICONV_OPTION
-               argstr[x++] = 's';
+               argstr[x++] = 's'; /* symlink iconv translation support */
 #endif
-               argstr[x++] = 'f';
+               argstr[x++] = 'f'; /* flist I/O-error safety support */
+               argstr[x++] = 'x'; /* xattr hardlink optimization not supported */
        }
 
        if (x >= (int)sizeof argstr) { /* Not possible... */
index 39f662745a90e91a97c62ab6762419aed1509648..571b7da6e0fb44bd3387abba45f1693257a5e058 100644 (file)
@@ -30,6 +30,7 @@ extern int inc_recurse;
 extern int log_before_transfer;
 extern int stdout_format_has_i;
 extern int logfile_format_has_i;
+extern int want_xattr_optim;
 extern int csum_length;
 extern int read_batch;
 extern int write_batch;
@@ -583,14 +584,16 @@ int recv_files(int f_in, int f_out, char *local_name)
                        rprintf(FINFO, "recv_files(%s)\n", fname);
 
 #ifdef SUPPORT_XATTRS
-               if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
+               if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
+                && !(want_xattr_optim && BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
                        recv_xattr_request(file, f_in);
 #endif
 
                if (!(iflags & ITEM_TRANSFER)) {
                        maybe_log_item(file, iflags, itemizing, xname);
 #ifdef SUPPORT_XATTRS
-                       if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
+                       if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
+                        && !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))
                                set_file_attrs(fname, file, NULL, fname, 0);
 #endif
                        if (iflags & ITEM_IS_NEW) {
index 3874344755f1f39a265d5c32c3098c39a3d7f995..5adc2fd89cbd55eee03bfbfc324de89bdfab9e02 100644 (file)
--- a/sender.c
+++ b/sender.c
@@ -29,6 +29,7 @@ extern int inc_recurse;
 extern int log_before_transfer;
 extern int stdout_format_has_i;
 extern int logfile_format_has_i;
+extern int want_xattr_optim;
 extern int csum_length;
 extern int append_mode;
 extern int io_error;
@@ -177,7 +178,8 @@ static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
        if (iflags & ITEM_XNAME_FOLLOWS)
                write_vstring(f_out, buf, len);
 #ifdef SUPPORT_XATTRS
-       if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
+       if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
+        && !(want_xattr_optim && BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
                send_xattr_request(fname, file, f_out);
 #endif
 }
@@ -258,7 +260,8 @@ void send_files(int f_in, int f_out)
                        rprintf(FINFO, "send_files(%d, %s%s%s)\n", ndx, path,slash,fname);
 
 #ifdef SUPPORT_XATTRS
-               if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
+               if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
+                && !(want_xattr_optim && BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
                        recv_xattr_request(file, f_in);
 #endif