- 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().
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;
#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;
#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
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;
#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
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... */
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;
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) {
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;
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
}
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