hardlinks not working with inode number > 2^31 [PATCH]

Paul Slootman paul+rsync at wurtel.net
Mon Feb 4 15:13:59 GMT 2008


On Mon 04 Feb 2008, Paul Slootman wrote:

> value, and then it works.  This looks like an attempt to save space,
> using 64 bits only when necessary. However the test seems flawed...

Adding some debug stuff shows:

hashtable_create(size=512, key64=1)
        sizeof (struct ht_int64_node)=16, sizeof (struct ht_int32_node)=16

Both structs are the same size. This is de declaration:

struct ht_int32_node {
        void *data;               
        int32 key;
};

struct ht_int64_node {
        void *data;
        int64 key;
};

Due to alignment padding, both will be padded out to 16 bytes.

Unfortunately this means that checking the size of this won't help to
determine which struct version is being used. I suggest that the table
struct is extended to note whether 64-bit values are used or not.  Patch
attached; with this patch it Works For Me (tm).


Paul Slootman


diff -ru ../orig/rsync.h ./rsync.h
--- ../orig/rsync.h	2007-12-08 20:39:47.000000000 +0100
+++ ./rsync.h	2008-02-04 16:05:37.622440950 +0100
@@ -540,6 +540,7 @@
 	void *nodes;
 	int32 size, entries;
 	uint32 node_size;
+	int     key64;
 };
 
 struct ht_int32_node {

diff -ru ../orig/hashtable.c ./hashtable.c
--- ../orig/hashtable.c	2007-09-03 06:46:57.000000000 +0200
+++ ./hashtable.c	2008-02-04 16:09:25.578091067 +0100
@@ -41,6 +41,7 @@
 	tbl->size = size;
 	tbl->entries = 0;
 	tbl->node_size = node_size;
+	tbl->key64 = key64;
 
 	return tbl;
 }
@@ -55,7 +56,6 @@
  * already existing.  Returns NULL if not allocating and not found. */
 void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
 {
-	int key64 = (tbl->node_size > sizeof (struct ht_int32_node));
 	struct ht_int32_node *node;
 	uint32 ndx;
 
@@ -71,7 +71,7 @@
 
 		for (i = size / 2; i-- > 0; ) {
 			struct ht_int32_node *move_node = HT_NODE(tbl, old_nodes, i);
-			int64 move_key = HT_KEY(move_node, key64);
+			int64 move_key = HT_KEY(move_node, tbl->key64);
 			if (move_key == 0)
 				continue;
 			node = hashtable_find(tbl, move_key, 1);
@@ -81,7 +81,7 @@
 		free(old_nodes);
 	}
 
-	if (!key64) {
+	if (!tbl->key64) {
 		/* Based on Jenkins One-at-a-time hash. */
 		uchar buf[4], *keyp = buf;
 		int i;
@@ -123,7 +123,7 @@
 
 		ndx &= tbl->size - 1;
 		node = HT_NODE(tbl, tbl->nodes, ndx);
-		nkey = HT_KEY(node, key64);
+		nkey = HT_KEY(node, tbl->key64);
 
 		if (nkey == key)
 			return node;
@@ -136,7 +136,7 @@
 	}
 
 	/* Take over this empty spot and then return the node. */
-	if (key64)
+	if (tbl->key64)
 		((struct ht_int64_node*)node)->key = key;
 	else
 		node->key = key;


More information about the rsync mailing list