+static int32 *hlink_list;
+static int32 hlink_count;
+
+/* Analyze the data in the hlink_list[], remove items that aren't multiply
+ * linked, and replace the dev+inode data with the hlindex+next linked list. */
+static void link_idev_data(void)
+{
+ int32 from, to, start;
+ struct file_struct *file, *file_next;
+ struct idev *idev, *idev_next;
+ struct hlist *hl;
+
+ alloc_pool_t hlink_pool;
+ alloc_pool_t idev_pool = the_file_list->hlink_pool;
+
+ hlink_pool = pool_create(128 * 1024, sizeof (struct hlist), out_of_memory, POOL_INTERN);
+
+ for (from = to = 0; from < hlink_count; from++) {
+ start = from;
+ for (file = FPTR(hlink_list[from]), idev = F_IDEV(file);
+ from < hlink_count-1;
+ file = file_next, idev = idev_next)
+ {
+ file_next = FPTR(hlink_list[from+1]);
+ idev_next = F_IDEV(file_next);
+ if (!LINKED(idev, idev_next))
+ break;
+ pool_free(idev_pool, 0, idev);
+ hl = pool_talloc(hlink_pool, struct hlist, 1,
+ "hlink_list");
+ hl->hlindex = to;
+ hl->next = hlink_list[++from];
+ hl->dest_used = 0;
+ F_HLIST(file) = hl;
+ }
+ pool_free(idev_pool, 0, idev);
+ if (from > start) {
+ int head = hlink_list[start];
+ hl = pool_talloc(hlink_pool, struct hlist, 1,
+ "hlink_list");
+ FPTR(head)->flags |= FLAG_HLINK_FIRST;
+ hl->hlindex = to;
+ hl->next = head;
+ hl->dest_used = 0;
+ hlink_list[to++] = head;
+ file->flags |= FLAG_HLINK_LAST;
+ F_HLIST(file) = hl;
+ } else
+ file->flags &= ~FLAG_HLINK_INFO;
+ }
+
+ if (!to) {
+ free(hlink_list);
+ hlink_list = NULL;
+ pool_destroy(hlink_pool);
+ hlink_pool = NULL;
+ } else {
+ hlink_count = to;
+ hlink_list = realloc_array(hlink_list, int32, hlink_count);
+ if (!hlink_list)
+ out_of_memory("init_hard_links");
+ }
+ the_file_list->hlink_pool = hlink_pool;
+ pool_destroy(idev_pool);
+}