Another xattr "internal abbrev" fix for an xattr object that is
authorWayne Davison <wayned@samba.org>
Sun, 13 Jan 2008 05:41:21 +0000 (21:41 -0800)
committerWayne Davison <wayned@samba.org>
Sun, 13 Jan 2008 06:16:37 +0000 (22:16 -0800)
shared by multiple files:  handle the case where one file has an
abbreviated item set correctly, but a following item does not.
Also extended testsuite/xattrs.test to verify that this works.

generator.c
testsuite/xattrs.test
xattrs.c

index c961ad2..a0bf08e 100644 (file)
@@ -945,10 +945,6 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
                        return -1;
                if (itemizing)
                        itemize(cmpbuf, file, ndx, 0, sxp, ITEM_LOCAL_CHANGE, 0, NULL);
-#ifdef SUPPORT_XATTRS
-               if (preserve_xattrs)
-                       xattr_clear_locals(file);
-#endif
                if (maybe_ATTRS_REPORT
                 && ((!itemizing && verbose && match_level == 2)
                  || (verbose > 1 && match_level == 3))) {
index ab022cd..97c5f8d 100644 (file)
@@ -34,18 +34,19 @@ case "`xattr 2>&1`" in
     ;;
 esac
 
-makepath "$fromdir/foo"
+makepath "$fromdir/foo/bar"
 echo now >"$fromdir/file0"
 echo something >"$fromdir/file1"
 echo else >"$fromdir/file2"
 echo deep >"$fromdir/foo/file3"
 echo normal >"$fromdir/file4"
+echo deeper >"$fromdir/foo/bar/file5"
 
 makepath "$chkdir/foo"
 echo wow >"$chkdir/file1"
 cp -p "$fromdir/foo/file3" "$chkdir/foo"
 
-files='foo file0 file1 file2 foo/file3 file4'
+files='foo file0 file1 file2 foo/file3 file4 foo/bar/file5'
 
 cd "$fromdir"
 
@@ -61,10 +62,10 @@ xset user.foo foo file2
 xset user.bar bar file2
 xset user.long 'a long attribute for our new file that tests to ensure that this works' file2
 
-xset user.foo 'new foo' foo/file3
-xset user.bar 'new bar' foo/file3
-xset user.long 'this is also a long attribute that will be truncated in the initial data send' foo/file3
-xset user.equal 'this long attribute should remain the same and not need to be transferred' foo/file3
+xset user.foo 'new foo' foo/file3 foo/bar/file5
+xset user.bar 'new bar' foo/file3 foo/bar/file5
+xset user.long 'this is also a long attribute that will be truncated in the initial data send' foo/file3 foo/bar/file5
+xset user.equal 'this long attribute should remain the same and not need to be transferred' foo/file3 foo/bar/file5
 
 xset user.short 'old short' "$chkdir/file1"
 xset user.extra 'remove me' "$chkdir/file1"
index 24a01c1..61d4f60 100644 (file)
--- a/xattrs.c
+++ b/xattrs.c
@@ -47,7 +47,6 @@ extern int checksum_seed;
 #define XSTATE_ABBREV  0
 #define XSTATE_DONE    1
 #define XSTATE_TODO    2
-#define XSTATE_LOCAL   3
 
 #define USER_PREFIX "user."
 #define UPRE_LEN ((int)sizeof USER_PREFIX - 1)
@@ -472,9 +471,11 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
                if (rxa->datum_len <= MAX_FULL_DATUM)
                        continue;
                switch (rxa->datum[0]) {
-               case XSTATE_LOCAL:
-                       /* Items set locally will get cached by receiver. */
-                       rxa->datum[0] = XSTATE_DONE;
+               case XSTATE_ABBREV:
+                       /* Items left abbreviated matched the sender's checksum, so
+                        * the receiver will cache the local data for future use. */
+                       if (am_generator)
+                               rxa->datum[0] = XSTATE_DONE;
                        continue;
                case XSTATE_TODO:
                        break;
@@ -508,27 +509,6 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
        write_byte(f_out, 0); /* end the list */
 }
 
-/* Any items set locally by the generator that the receiver doesn't
- * get told about get changed back to XSTATE_ABBREV. */
-void xattr_clear_locals(struct file_struct *file)
-{
-       item_list *lst = rsync_xal_l.items;
-       rsync_xa *rxa;
-       int cnt;
-
-       if (F_XATTR(file) < 0)
-               return;
-
-       lst += F_XATTR(file);
-       cnt = lst->count;
-       for (rxa = lst->items; cnt--; rxa++) {
-               if (rxa->datum_len <= MAX_FULL_DATUM)
-                       continue;
-               if (rxa->datum[0] == XSTATE_LOCAL)
-                       rxa->datum[0] = XSTATE_ABBREV;
-       }
-}
-
 /* When called by the sender, read the request from the generator and mark
  * any needed xattrs with a flag that lets us know they need to be sent to
  * the receiver.  When called by the receiver, reads the sent data and
@@ -751,8 +731,6 @@ static int rsync_xal_set(const char *fname, item_list *xalp,
                                sxp->st.st_mtime = (time_t)-1;
 
                        if (am_generator) { /* generator items stay abbreviated */
-                               if (rxas[i].datum[0] == XSTATE_ABBREV)
-                                       rxas[i].datum[0] = XSTATE_LOCAL;
                                free(ptr);
                                continue;
                        }