Fixed an "Internal abbrev error" when dealing with an xattr value
authorWayne Davison <wayned@samba.org>
Mon, 9 Jun 2008 03:26:22 +0000 (20:26 -0700)
committerWayne Davison <wayned@samba.org>
Mon, 9 Jun 2008 03:40:11 +0000 (20:40 -0700)
that is unchanged on an early file, and changed on a later file.
Added 2 new test cases to ensure this stays fixed.

generator.c
testsuite/xattrs.test
xattrs.c

index 0ac8642..2ae88db 100644 (file)
@@ -697,8 +697,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
                        if (iflags & ITEM_XNAME_FOLLOWS)
                                write_vstring(sock_f_out, xname, strlen(xname));
 #ifdef SUPPORT_XATTRS
                        if (iflags & ITEM_XNAME_FOLLOWS)
                                write_vstring(sock_f_out, xname, strlen(xname));
 #ifdef SUPPORT_XATTRS
-                       if (iflags & ITEM_REPORT_XATTR && !dry_run)
-                               send_xattr_request(NULL, file, sock_f_out);
+                       if (preserve_xattrs && !dry_run
+                        && iflags & (ITEM_REPORT_XATTR|ITEM_TRANSFER)) {
+                               send_xattr_request(NULL, file,
+                                       iflags & ITEM_REPORT_XATTR ? sock_f_out : -1);
+                       }
 #endif
                } else if (ndx >= 0) {
                        enum logcode code = logfile_format_has_i ? FINFO : FCLIENT;
 #endif
                } else if (ndx >= 0) {
                        enum logcode code = logfile_format_has_i ? FINFO : FCLIENT;
index 4f2c6cb..11b53c5 100644 (file)
@@ -91,12 +91,12 @@ cd "$todir"
 xls $files | diff $diffopt "$scratchdir/xattrs.txt" -
 
 cd "$fromdir"
 xls $files | diff $diffopt "$scratchdir/xattrs.txt" -
 
 cd "$fromdir"
+rm -rf "$todir"
+
 xset user.nice 'this is nice, but different' file1
 
 xls $files >"$scratchdir/xattrs.txt"
 
 xset user.nice 'this is nice, but different' file1
 
 xls $files >"$scratchdir/xattrs.txt"
 
-rm -rf "$todir"
-
 checkit "$RSYNC -aiX --fake-super --link-dest=../chk . ../to" "$chkdir" "$todir"
 
 cd "$todir"
 checkit "$RSYNC -aiX --fake-super --link-dest=../chk . ../to" "$chkdir" "$todir"
 
 cd "$todir"
@@ -109,5 +109,31 @@ if [ -s "$scratchdir/ls-diff" ]; then
     exit 1
 fi
 
     exit 1
 fi
 
+cd "$fromdir"
+rm -rf "$todir" "$chkdir"
+
+rsync -aX file1 file2
+rsync -aX file1 file2 ../chk/
+rsync -aX --del ../chk/ .
+rsync -aX file1 ../lnk/
+
+xls file1 file2 >"$scratchdir/xattrs.txt"
+
+checkit "$RSYNC -aiiX --copy-dest=../lnk . ../to" "$chkdir" "$todir"
+
+cd "$todir"
+xls file1 file2 | diff $diffopt "$scratchdir/xattrs.txt" -
+
+cd "$fromdir"
+rm "$todir/file2"
+
+echo extra >file1
+rsync -aX file1 ../chk/
+
+checkit "$RSYNC -aiiX . ../to" "$chkdir" "$todir"
+
+cd "$todir"
+xls file1 file2 | diff $diffopt "$scratchdir/xattrs.txt" -
+
 # The script would have aborted on error, so getting here means we've won.
 exit 0
 # The script would have aborted on error, so getting here means we've won.
 exit 0
index b6a82e4..349fbf4 100644 (file)
--- a/xattrs.c
+++ b/xattrs.c
@@ -503,9 +503,11 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
        return !xattrs_equal;
 }
 
        return !xattrs_equal;
 }
 
-/* When called by the generator with a NULL fname, this tells the sender
- * which abbreviated xattr values we need.  When called by the sender
- * (with a non-NULL fname), we send all the extra xattr data it needs. */
+/* When called by the generator (with a NULL fname), this tells the sender
+ * all the abbreviated xattr values we need.  When called by the sender
+ * (with a non-NULL fname), we send all the extra xattr data it needs.
+ * The generator may also call with f_out < 0 to just change all the
+ * XSTATE_ABBREV states into XSTATE_DONE. */
 void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
 {
        item_list *lst = rsync_xal_l.items;
 void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
 {
        item_list *lst = rsync_xal_l.items;
@@ -524,6 +526,7 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
                                rxa->datum[0] = XSTATE_DONE;
                        continue;
                case XSTATE_TODO:
                                rxa->datum[0] = XSTATE_DONE;
                        continue;
                case XSTATE_TODO:
+                       assert(f_out >= 0);
                        break;
                default:
                        continue;
                        break;
                default:
                        continue;
@@ -552,7 +555,8 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
                }
        }
 
                }
        }
 
-       write_byte(f_out, 0); /* end the list */
+       if (f_out >= 0)
+               write_byte(f_out, 0); /* end the list */
 }
 
 /* When called by the sender, read the request from the generator and mark
 }
 
 /* When called by the sender, read the request from the generator and mark