+ /* Otherwise, take over this empty spot and then return it. */
+ tbl->buckets[bkt].key = key;
+ tbl->entries++;
+ return &tbl->buckets[bkt];
+}
+
+struct idev_node *idev_node(int64 dev, int64 ino)
+{
+ static struct idev_node *dev_node = NULL;
+ struct ihash_table *tbl;
+
+ if (!dev_node || dev_node->key != dev) {
+ /* We keep a separate hash table of inodes for every device. */
+ dev_node = ihash_node(dev_tbl, dev);
+ if (!(tbl = dev_node->data))
+ tbl = dev_node->data = ihash_create(512);
+ } else
+ tbl = dev_node->data;
+
+ return ihash_node(tbl, ino);
+}
+
+void idev_destroy(void)
+{
+ int i;
+
+ for (i = 0; i < dev_tbl->size; i++) {
+ if (dev_tbl->buckets[i].data)
+ ihash_destroy(dev_tbl->buckets[i].data);
+ }
+
+ ihash_destroy(dev_tbl);
+}
+
+static int hlink_compare_gnum(int *int1, int *int2)
+{
+ struct file_struct *f1 = cur_flist->sorted[*int1];
+ struct file_struct *f2 = cur_flist->sorted[*int2];
+ int32 gnum1 = F_HL_GNUM(f1);
+ int32 gnum2 = F_HL_GNUM(f2);
+
+ if (gnum1 != gnum2)
+ return gnum1 > gnum2 ? 1 : -1;
+
+ return *int1 > *int2 ? 1 : -1;
+}
+
+static void match_gnums(int32 *ndx_list, int ndx_count)
+{
+ int32 from, prev;
+ struct file_struct *file, *file_next;
+ int32 gnum, gnum_next;
+