summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--compat.c5
-rw-r--r--generator.c5
-rw-r--r--options.c7
-rw-r--r--receiver.c7
-rw-r--r--sender.c7
6 files changed, 25 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index 9e50fe0c..22766ce6 100644
--- 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().
diff --git a/compat.c b/compat.c
index 23ed53a9..2454937f 100644
--- 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
diff --git a/generator.c b/generator.c
index 0f7a5169..63399d3d 100644
--- a/generator.c
+++ b/generator.c
@@ -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
diff --git a/options.c b/options.c
index 0aa64bf0..5b061ade 100644
--- 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... */
diff --git a/receiver.c b/receiver.c
index 39f66274..571b7da6 100644
--- a/receiver.c
+++ b/receiver.c
@@ -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) {
diff --git a/sender.c b/sender.c
index 38743447..5adc2fd8 100644
--- 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