+--- old/t_unsafe.c
++++ new/t_unsafe.c
+@@ -24,7 +24,11 @@
+
+ #include "rsync.h"
+
+-int dry_run, read_only, list_only, verbose;
++int dry_run = 0;
++int am_root = 0;
++int read_only = 0;
++int list_only = 0;
++int verbose = 0;
+ int preserve_perms = 0;
+
+ int
+--- old/tls.c
++++ new/tls.c
+@@ -39,6 +39,7 @@
+
+ /* These are to make syscall.o shut up. */
+ int dry_run = 0;
++int am_root = 0;
+ int read_only = 1;
+ int list_only = 0;
+ int preserve_perms = 0;
+--- old/trimslash.c
++++ new/trimslash.c
+@@ -23,6 +23,7 @@
+
+ /* These are to make syscall.o shut up. */
+ int dry_run = 0;
++int am_root = 0;
+ int read_only = 1;
+ int list_only = 0;
+ int preserve_perms = 0;
+--- old/xattr.c
++++ new/xattr.c
+@@ -43,11 +43,16 @@ extern unsigned int file_struct_len;
+ #define SPRE_LEN ((int)sizeof SYSTEM_PREFIX - 1)
+
+ #ifdef HAVE_LINUX_XATTRS
+-#define RPRE_LEN 0
++#define RSYNC_PREFIX USER_PREFIX "rsync."
+ #else
+ #define RSYNC_PREFIX "rsync."
+-#define RPRE_LEN ((int)sizeof RSYNC_PREFIX - 1)
+ #endif
++#define RPRE_LEN ((int)sizeof RSYNC_PREFIX - 1)
++
++#define XSTAT_ATTR RSYNC_PREFIX "%stat"
++#define XSTAT_LEN ((int)sizeof XSTAT_ATTR - 1)
++
++#define CENT_POS RPRE_LEN
+
+ typedef struct {
+ char *datum, *name;
+@@ -148,6 +153,10 @@ static int rsync_xal_get(const char *fna
+ continue;
+ #endif
+
++ if (am_root < 0 && name_len == XSTAT_LEN + 1
++ && name[CENT_POS] == '%' && strcmp(name, XSTAT_ATTR) == 0)
++ continue;
++
+ datum_len = sys_lgetxattr(fname, name, NULL, 0);
+ if (datum_len < 0) {
+ if (errno == ENOTSUP)
+@@ -177,6 +186,13 @@ static int rsync_xal_get(const char *fna
+ return -1;
+ }
+ }
++#ifdef HAVE_LINUX_XATTRS
++ if (am_root < 0 && name_len > RPRE_LEN
++ && HAS_PREFIX(name, RSYNC_PREFIX)) {
++ name += RPRE_LEN;
++ name_len -= RPRE_LEN;
++ }
++#endif
+ rxas = EXPAND_ITEM_LIST(xalp, rsync_xa, RSYNC_XAL_INITIAL);
+ rxas->name = ptr + datum_len;
+ rxas->datum = ptr;
+@@ -299,10 +315,8 @@ void receive_xattr(struct file_struct *f
+ size_t name_len = read_int(f);
+ size_t datum_len = read_int(f);
+ size_t extra_len = am_root < 0 ? RPRE_LEN : 0;
+-#ifndef HAVE_LINUX_XATTRS
+ if (datum_len + extra_len < datum_len)
+ out_of_memory("receive_xattr"); /* overflow */
+-#endif
+ if (name_len + datum_len + extra_len < name_len)
+ out_of_memory("receive_xattr"); /* overflow */
+ ptr = new_array(char, name_len + datum_len + extra_len);
+@@ -313,6 +327,10 @@ void receive_xattr(struct file_struct *f
+ read_buf(f, ptr, datum_len);
+ #ifdef HAVE_LINUX_XATTRS
+ /* Non-root can only save the user namespace. */
++ if (am_root < 0 && !HAS_PREFIX(name, USER_PREFIX)) {
++ name -= RPRE_LEN;
++ memcpy(name, RSYNC_PREFIX, RPRE_LEN);
++ } else
+ if (!am_root && !HAS_PREFIX(name, USER_PREFIX)) {
+ free(ptr);
+ continue;
+@@ -333,6 +351,11 @@ void receive_xattr(struct file_struct *f
+ continue;
+ }