aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2009-04-26 07:28:55 -0700
committerWayne Davison <wayned@samba.org>2009-04-26 07:43:32 -0700
commita8e6e1486960fe2e9ac190ad53e9830f0f3f900a (patch)
tree3468f982f5fb605a0d882fe1d19c096502111d59
parent307555eba3720362922cf25c15991b21f0e72dab (diff)
downloadandroid_external_rsync-a8e6e1486960fe2e9ac190ad53e9830f0f3f900a.tar.gz
android_external_rsync-a8e6e1486960fe2e9ac190ad53e9830f0f3f900a.tar.bz2
android_external_rsync-a8e6e1486960fe2e9ac190ad53e9830f0f3f900a.zip
Change sending/receiving/storing of the rdev value for special files.
Since the value is not needed, protocol 31 no longer sends it, while older protocols are optimized so the sender just sends a valid rdev value as efficiently as possible. The receiver no longer caches an rdev value for special files, and the generator will always pass a 0 rdev value to do_mknod() for special files. Fixes bug #6280.
-rw-r--r--flist.c32
-rw-r--r--generator.c12
-rw-r--r--rsync.h2
-rw-r--r--xattrs.c4
4 files changed, 32 insertions, 18 deletions
diff --git a/flist.c b/flist.c
index d7a70a61..2af7e88b 100644
--- a/flist.c
+++ b/flist.c
@@ -442,8 +442,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
else
mode = file->mode;
- if ((preserve_devices && IS_DEVICE(mode))
- || (preserve_specials && IS_SPECIAL(mode))) {
+ if (preserve_devices && IS_DEVICE(mode)) {
if (protocol_version < 28) {
if (tmp_rdev == rdev)
xflags |= XMIT_SAME_RDEV_pre28;
@@ -458,6 +457,17 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
if (protocol_version < 30 && (uint32)minor(rdev) <= 0xFFu)
xflags |= XMIT_RDEV_MINOR_8_pre30;
}
+ } else if (preserve_specials && IS_SPECIAL(mode) && protocol_version < 31) {
+ /* Special files don't need an rdev number, so just make
+ * the historical transmission of the value efficient. */
+ if (protocol_version < 28)
+ xflags |= XMIT_SAME_RDEV_pre28;
+ else {
+ rdev = MAKEDEV(major(rdev), 0);
+ xflags |= XMIT_SAME_RDEV_MAJOR;
+ if (protocol_version < 30)
+ xflags |= XMIT_RDEV_MINOR_8_pre30;
+ }
} else if (protocol_version < 28)
rdev = MAKEDEV(0, 0);
if (!preserve_uid || ((uid_t)F_OWNER(file) == uid && *lastname))
@@ -593,7 +603,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
}
}
if ((preserve_devices && IS_DEVICE(mode))
- || (preserve_specials && IS_SPECIAL(mode))) {
+ || (preserve_specials && IS_SPECIAL(mode) && protocol_version < 31)) {
if (protocol_version < 28) {
if (!(xflags & XMIT_SAME_RDEV_pre28))
write_int(f, (int)rdev);
@@ -762,8 +772,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
uid = F_OWNER(first);
if (preserve_gid)
gid = F_GROUP(first);
- if ((preserve_devices && IS_DEVICE(mode))
- || (preserve_specials && IS_SPECIAL(mode))) {
+ if (preserve_devices && IS_DEVICE(mode)) {
uint32 *devp = F_RDEV_P(first);
rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
extra_len += DEV_EXTRA_CNT * EXTRA_LEN;
@@ -822,7 +831,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
}
if ((preserve_devices && IS_DEVICE(mode))
- || (preserve_specials && IS_SPECIAL(mode))) {
+ || (preserve_specials && IS_SPECIAL(mode) && protocol_version < 31)) {
if (protocol_version < 28) {
if (!(xflags & XMIT_SAME_RDEV_pre28))
rdev = (dev_t)read_int(f);
@@ -838,7 +847,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
rdev_minor = read_int(f);
rdev = MAKEDEV(rdev_major, rdev_minor);
}
- extra_len += DEV_EXTRA_CNT * EXTRA_LEN;
+ if (IS_DEVICE(mode))
+ extra_len += DEV_EXTRA_CNT * EXTRA_LEN;
file_length = 0;
} else if (protocol_version < 28)
rdev = MAKEDEV(0, 0);
@@ -979,8 +989,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
}
}
- if ((preserve_devices && IS_DEVICE(mode))
- || (preserve_specials && IS_SPECIAL(mode))) {
+ if (preserve_devices && IS_DEVICE(mode)) {
uint32 *devp = F_RDEV_P(file);
DEV_MAJOR(devp) = major(rdev);
DEV_MINOR(devp) = minor(rdev);
@@ -1307,10 +1316,11 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
#endif
#ifdef HAVE_STRUCT_STAT_ST_RDEV
- if (IS_DEVICE(st.st_mode) || IS_SPECIAL(st.st_mode)) {
+ if (IS_DEVICE(st.st_mode)) {
tmp_rdev = st.st_rdev;
st.st_size = 0;
- }
+ } else if (IS_SPECIAL(st.st_mode))
+ st.st_size = 0;
#endif
file->flags = flags;
diff --git a/generator.c b/generator.c
index f3929ed7..1ccb55a2 100644
--- a/generator.c
+++ b/generator.c
@@ -931,8 +931,8 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
}
switch (type) {
case TYPE_DIR:
- break;
case TYPE_SPECIAL:
+ break;
case TYPE_DEVICE:
devp = F_RDEV_P(file);
if (sxp->st.st_rdev != MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)))
@@ -1429,8 +1429,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
if ((am_root && preserve_devices && IS_DEVICE(file->mode))
|| (preserve_specials && IS_SPECIAL(file->mode))) {
- uint32 *devp = F_RDEV_P(file);
- dev_t rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
+ dev_t rdev;
+ if (IS_DEVICE(file->mode)) {
+ uint32 *devp = F_RDEV_P(file);
+ rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
+ } else
+ rdev = 0;
if (statret == 0) {
int del_for_flag;
if (IS_DEVICE(file->mode)) {
@@ -1444,7 +1448,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
}
if (statret == 0
&& BITS_EQUAL(sx.st.st_mode, file->mode, _S_IFMT)
- && sx.st.st_rdev == rdev) {
+ && (IS_SPECIAL(sx.st.st_mode) || sx.st.st_rdev == rdev)) {
/* The device or special file is identical. */
set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
if (itemizing)
diff --git a/rsync.h b/rsync.h
index 1b0397e1..3656c767 100644
--- a/rsync.h
+++ b/rsync.h
@@ -96,7 +96,7 @@
/* This is used when working on a new protocol version in CVS, and should
* be a new non-zero value for each CVS change that affects the protocol.
* It must ALWAYS be 0 when the protocol goes final (and NEVER before)! */
-#define SUBPROTOCOL_VERSION 5
+#define SUBPROTOCOL_VERSION 6
/* We refuse to interoperate with versions that are not in this range.
* Note that we assume we'll work with later versions: the onus is on
diff --git a/xattrs.c b/xattrs.c
index b9034751..0eceb393 100644
--- a/xattrs.c
+++ b/xattrs.c
@@ -990,7 +990,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode)
fst.st_mode &= (_S_IFMT | CHMOD_BITS);
fmode = new_mode & (_S_IFMT | CHMOD_BITS);
- if (IS_DEVICE(fmode) || IS_SPECIAL(fmode)) {
+ if (IS_DEVICE(fmode)) {
uint32 *devp = F_RDEV_P(file);
rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
} else
@@ -1001,7 +1001,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode)
| (S_ISDIR(fst.st_mode) ? 0700 : 0600);
if (fst.st_mode != mode)
do_chmod(fname, mode);
- if (!IS_DEVICE(fst.st_mode) && !IS_SPECIAL(fst.st_mode))
+ if (!IS_DEVICE(fst.st_mode))
fst.st_rdev = 0; /* just in case */
if (mode == fmode && fst.st_rdev == rdev