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);
                        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))) {
                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
 
     ;;
 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 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"
 
 
 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"
 
 
 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.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"
 
 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_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)
 
 #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]) {
                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;
                        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 */
 }
 
        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
 /* 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 */
                                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;
                        }
                                free(ptr);
                                continue;
                        }