Commit a8e6e148 authored by Wayne Davison's avatar Wayne Davison

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.
parent 307555eb
......@@ -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;
......
......@@ -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)
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment