From b769ad6a3e7ef871ea0aabd5b033018ba6cdbb90 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sat, 12 Jan 2008 21:41:21 -0800 Subject: [PATCH] Another xattr "internal abbrev" fix for an xattr object that is 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 | 4 ---- testsuite/xattrs.test | 13 +++++++------ xattrs.c | 32 +++++--------------------------- 3 files changed, 12 insertions(+), 37 deletions(-) diff --git a/generator.c b/generator.c index c961ad2a..a0bf08ee 100644 --- a/generator.c +++ b/generator.c @@ -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))) { diff --git a/testsuite/xattrs.test b/testsuite/xattrs.test index ab022cdf..97c5f8d3 100644 --- a/testsuite/xattrs.test +++ b/testsuite/xattrs.test @@ -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" diff --git a/xattrs.c b/xattrs.c index 24a01c1a..61d4f607 100644 --- 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; } -- 2.34.1