diff options
| author | Dylan Simon <dylan@dylex.net> | 2010-06-27 12:37:58 -0400 |
|---|---|---|
| committer | Dylan Simon <dylan@dylex.net> | 2010-06-27 12:37:58 -0400 |
| commit | 2ee87bd118ff706c5a6db93b6ff6d0dcc0f7cb54 (patch) | |
| tree | c6ed3c70341c1b3b2aa9d186200f24caf3fc9004 | |
| parent | b1f36fb98cbc5646cf79dd6c3ec61f270923bbaf (diff) | |
| parent | e51bb8f330d6b6ee3979bb0538e42da997c50d75 (diff) | |
| download | android_external_rsync-2ee87bd118ff706c5a6db93b6ff6d0dcc0f7cb54.tar.gz android_external_rsync-2ee87bd118ff706c5a6db93b6ff6d0dcc0f7cb54.tar.bz2 android_external_rsync-2ee87bd118ff706c5a6db93b6ff6d0dcc0f7cb54.zip | |
Merge remote branch 'rsync/b3.0.x'
| -rw-r--r-- | compat.c | 2 | ||||
| -rw-r--r-- | flist.c | 16 | ||||
| -rw-r--r-- | hashtable.c | 9 | ||||
| -rw-r--r-- | hlink.c | 24 | ||||
| -rw-r--r-- | io.c | 3 |
5 files changed, 37 insertions, 17 deletions
@@ -24,6 +24,7 @@ int remote_protocol = 0; int file_extra_cnt = 0; /* count of file-list extras that everyone gets */ int inc_recurse = 0; +int compat_flags = 0; int use_safe_inc_flist = 0; extern int verbose; @@ -248,7 +249,6 @@ void setup_protocol(int f_out,int f_in) exit_cleanup(RERR_PROTOCOL); } } else if (protocol_version >= 30) { - int compat_flags; if (am_server) { compat_flags = allow_inc_recurse ? CF_INC_RECURSE : 0; #if defined HAVE_LUTIMES && defined HAVE_UTIMES @@ -118,7 +118,7 @@ int flist_eof = 0; /* all the file-lists are now known */ * will survive just long enough to be used by send_file_entry(). */ static DEV_T tmp_rdev; #ifdef SUPPORT_HARD_LINKS -static int64 tmp_dev, tmp_ino; +static int64 tmp_dev = -1, tmp_ino; #endif static char tmp_sum[MAX_DIGEST_LEN]; @@ -480,7 +480,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, modtime = file->modtime; #ifdef SUPPORT_HARD_LINKS - if (tmp_dev != 0) { + if (tmp_dev != -1) { if (protocol_version >= 30) { struct ht_int64_node *np = idev_find(tmp_dev, tmp_ino); first_hlink_ndx = (int32)(long)np->data - 1; @@ -598,15 +598,17 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, #endif #ifdef SUPPORT_HARD_LINKS - if (tmp_dev != 0 && protocol_version < 30) { + if (tmp_dev != -1 && protocol_version < 30) { + /* Older protocols expect the dev number to be transmitted + * 1-incremented so that it is never zero. */ if (protocol_version < 26) { /* 32-bit dev_t and ino_t */ - write_int(f, (int32)dev); + write_int(f, (int32)(dev+1)); write_int(f, (int32)tmp_ino); } else { /* 64-bit dev_t and ino_t */ if (!(xflags & XMIT_SAME_DEV_pre30)) - write_longint(f, dev); + write_longint(f, dev+1); write_longint(f, tmp_ino); } } @@ -1259,10 +1261,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, if (protocol_version >= 28 ? (!S_ISDIR(st.st_mode) && st.st_nlink > 1) : S_ISREG(st.st_mode)) { - tmp_dev = (int64)st.st_dev + 1; + tmp_dev = (int64)st.st_dev; tmp_ino = (int64)st.st_ino; } else - tmp_dev = 0; + tmp_dev = -1; } #endif diff --git a/hashtable.c b/hashtable.c index ed29ee91..0524e24b 100644 --- a/hashtable.c +++ b/hashtable.c @@ -41,7 +41,7 @@ struct hashtable *hashtable_create(int size, int key64) tbl->size = size; tbl->entries = 0; tbl->node_size = node_size; - tbl->key64 = key64; + tbl->key64 = key64 ? 1 : 0; return tbl; } @@ -60,6 +60,11 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing) struct ht_int32_node *node; uint32 ndx; + if (key64 ? key == 0 : (int32)key == 0) { + rprintf(FERROR, "Internal hashtable error: illegal key supplied!\n"); + exit_cleanup(RERR_MESSAGEIO); + } + if (allocate_if_missing && tbl->entries > HASH_LOAD_LIMIT(tbl->size)) { void *old_nodes = tbl->nodes; int size = tbl->size * 2; @@ -142,7 +147,7 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing) if (key64) ((struct ht_int64_node*)node)->key = key; else - node->key = key; + node->key = (int32)key; tbl->entries++; return node; } @@ -57,7 +57,7 @@ static struct file_list *hlink_flist; void init_hard_links(void) { if (am_sender || protocol_version < 30) - dev_tbl = hashtable_create(16, SIZEOF_INT64 == 8); + dev_tbl = hashtable_create(16, 1); else if (inc_recurse) prior_hlinks = hashtable_create(1024, 0); } @@ -67,11 +67,12 @@ struct ht_int64_node *idev_find(int64 dev, int64 ino) static struct ht_int64_node *dev_node = NULL; struct hashtable *tbl; - if (!dev_node || dev_node->key != dev) { + /* Note that some OSes have a dev == 0, so increment to avoid storing a 0. */ + if (!dev_node || dev_node->key != dev+1) { /* We keep a separate hash table of inodes for every device. */ - dev_node = hashtable_find(dev_tbl, dev, 1); + dev_node = hashtable_find(dev_tbl, dev+1, 1); if (!(tbl = dev_node->data)) - tbl = dev_node->data = hashtable_create(512, SIZEOF_INT64 == 8); + tbl = dev_node->data = hashtable_create(512, 1); } else tbl = dev_node->data; @@ -533,8 +534,19 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx, if (inc_recurse) { int gnum = F_HL_GNUM(file); struct ht_int32_node *node = hashtable_find(prior_hlinks, gnum, 0); - assert(node != NULL && node->data != NULL); - assert(CVAL(node->data, 0) == 0); + if (node == NULL) { + rprintf(FERROR, "Unable to find a hlink node for %d (%s)\n", gnum, f_name(file, prev_name)); + exit_cleanup(RERR_MESSAGEIO); + } + if (node->data == NULL) { + rprintf(FERROR, "Hlink node data for %d is NULL (%s)\n", gnum, f_name(file, prev_name)); + exit_cleanup(RERR_MESSAGEIO); + } + if (CVAL(node->data, 0) != 0) { + rprintf(FERROR, "Hlink node data for %d already has path=%s (%s)\n", + gnum, (char*)node->data, f_name(file, prev_name)); + exit_cleanup(RERR_MESSAGEIO); + } free(node->data); if (!(node->data = strdup(our_name))) out_of_memory("finish_hard_link"); @@ -48,6 +48,7 @@ extern int flist_eof; extern int list_only; extern int read_batch; extern int csum_length; +extern int compat_flags; extern int protect_args; extern int checksum_seed; extern int protocol_version; @@ -1901,7 +1902,7 @@ void start_write_batch(int fd) * is involved. */ write_int(batch_fd, protocol_version); if (protocol_version >= 30) - write_byte(batch_fd, inc_recurse); + write_byte(batch_fd, compat_flags); write_int(batch_fd, checksum_seed); if (am_sender) |
