aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2010-06-26 16:13:20 -0700
committerWayne Davison <wayned@samba.org>2010-06-26 16:13:20 -0700
commit6b8756674421b575a9ea92cfc2cc62a179df18e4 (patch)
treeb39bea38a4ea7008646975dd9679aecf50a0dec9
parentb384d71e53e6f4eed3cb1811551773285f6b0a69 (diff)
downloadandroid_external_rsync-6b8756674421b575a9ea92cfc2cc62a179df18e4.tar.gz
android_external_rsync-6b8756674421b575a9ea92cfc2cc62a179df18e4.tar.bz2
android_external_rsync-6b8756674421b575a9ea92cfc2cc62a179df18e4.zip
Make sure our use of idev_find() hashtable is right
while also supporting older rsyncs that send dev == 0.
-rw-r--r--flist.c16
-rw-r--r--hlink.c9
2 files changed, 14 insertions, 11 deletions
diff --git a/flist.c b/flist.c
index 09824770..253dbe0a 100644
--- a/flist.c
+++ b/flist.c
@@ -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/hlink.c b/hlink.c
index 5ab9bb86..0c4ab4d6 100644
--- a/hlink.c
+++ b/hlink.c
@@ -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;