-+ rxas = EXPAND_ITEM_LIST(xalp, rsync_xa, RSYNC_XAL_INITIAL);
-+
- datum_size = sys_lgetxattr(fname, name, NULL, 0);
- if (datum_size < 0) {
- if (errno == ENOTSUP)
-@@ -287,10 +296,19 @@ void receive_xattr(struct file_struct *f
- out_of_memory("receive_xattr");
- read_buf(f, ptr, name_len);
- read_buf(f, ptr + name_len, datum_len);
-+
-+ if (am_root < 0 && name_len == sizeof FAKE_XATTR
-+ && ptr[10] == '%' && strcmp(ptr, FAKE_XATTR) == 0) {
-+ free(ptr);
-+ temp_xattr.count--;
-+ continue;
-+ }
-+
- rxa->name_len = name_len;
- rxa->datum_len = datum_len;
- rxa->name = ptr;
- rxa->datum = ptr + name_len;
-+
- #ifdef HAVE_OSX_XATTRS
- if (strncmp(rxa->name, UNIQUE_PREFIX, UPRE_LEN) == 0) {
- rxa->name_len -= UPRE_LEN;
-@@ -372,4 +390,146 @@ int set_xattr(const char *fname, const s
- return rsync_xal_set(fname, lst + ndx); /* TODO: This needs to return 1 if no xattrs changed! */
+ datum_len = name_len; /* Pass extra size to get_xattr_data() */
+ if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
+ return -1;
+@@ -236,6 +245,14 @@ static int rsync_xal_get(const char *fna
+ } else
+ name_offset = datum_len;
+
++#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 + name_offset;
+ memcpy(rxas->name, name, name_len);
+@@ -576,13 +593,9 @@ void receive_xattr(struct file_struct *f
+ size_t name_len = read_abbrevint(f);
+ size_t datum_len = read_abbrevint(f);
+ size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
+-#ifdef HAVE_LINUX_XATTRS
+- size_t extra_len = 0;
+-#else
+- size_t extra_len = am_root ? RPRE_LEN : 0;
++ size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
+ if (dget_len + extra_len < dget_len)
+ out_of_memory("receive_xattr"); /* overflow */
+-#endif
+ if (dget_len + extra_len + name_len < dget_len)
+ out_of_memory("receive_xattr"); /* overflow */
+ ptr = new_array(char, dget_len + extra_len + name_len);
+@@ -598,9 +611,14 @@ void receive_xattr(struct file_struct *f
+ }
+ #ifdef HAVE_LINUX_XATTRS
+ /* Non-root can only save the user namespace. */
+- if (!am_root && !HAS_PREFIX(name, USER_PREFIX)) {
+- free(ptr);
+- continue;
++ if (am_root <= 0 && !HAS_PREFIX(name, USER_PREFIX)) {
++ if (!am_root) {
++ free(ptr);
++ continue;
++ }
++ name -= RPRE_LEN;
++ name_len += RPRE_LEN;
++ memcpy(name, RSYNC_PREFIX, RPRE_LEN);
+ }
+ #else
+ /* This OS only has a user namespace, so we either
+@@ -618,6 +636,11 @@ void receive_xattr(struct file_struct *f
+ continue;
+ }
+ #endif
++ if (am_root < 0 && name_len == XSTAT_LEN + 1
++ && name[RPRE_LEN] == '%' && strcmp(name, XSTAT_ATTR) == 0) {
++ free(ptr);
++ continue;
++ }
+ rxa = EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, 1);
+ rxa->name = name;
+ rxa->datum = ptr;
+@@ -772,4 +795,150 @@ int set_xattr(const char *fname, const s
+ return rsync_xal_set(fname, lst + ndx, fnamecmp, sxp);