+#define LINKED(p1,p2) ((p1)->F_DEV == (p2)->F_DEV \
+ && (p1)->F_INODE == (p2)->F_INODE)
+
+/* Analyze the data in the hlink_list[], remove items that aren't multiply
+ * linked, and replace the dev+inode data with the head+next linked list. */
+static void link_idev_data(void)
+{
+ struct file_struct *head;
+ int from, to, start;
+
+ for (from = to = 0; from < hlink_count; from++) {
+ start = from;
+ head = hlink_list[start];
+ while (from < hlink_count-1
+ && LINKED(hlink_list[from], hlink_list[from+1])) {
+ hlink_list[from]->F_HEAD = head;
+ hlink_list[from]->F_NEXT = hlink_list[from+1];
+ from++;
+ }
+ if (from > start) {
+ hlink_list[from]->F_HEAD = head;
+ hlink_list[from]->F_NEXT = NULL;
+ hlink_list[to++] = head;
+ } else {
+ free((char*)head->link_u.idev);
+ head->link_u.idev = NULL;
+ }
+ }
+
+ if (!to) {
+ free(hlink_list);
+ hlink_list = NULL;
+ } else {
+ hlink_count = to;
+ if (!(hlink_list = realloc_array(hlink_list,
+ struct file_struct *, hlink_count)))
+ out_of_memory("init_hard_links");
+ }
+}