+/* Analyze the dev+inode data in the file-list by creating a list of all
+ * the items that have hlink data, sorting them, and matching up identical
+ * values into clusters. These will be a single linked list from last to
+ * first when we're done. */
+void match_hard_links(void)
+{
+ int32 from, prev, *ndx_list;
+ struct file_struct *file, *file_next;
+ struct idev *idev, *idev_next;
+ int i, ndx_count = 0;
+
+ if (!(ndx_list = new_array(int32, the_file_list->count)))
+ out_of_memory("match_hard_links");
+
+ for (i = 0; i < the_file_list->count; i++) {
+ if (F_IS_HLINKED(FPTR(i)))
+ ndx_list[ndx_count++] = i;
+ }
+
+ if (!ndx_count) {
+ free(ndx_list);
+ return;
+ }
+
+ qsort(ndx_list, ndx_count, sizeof ndx_list[0],
+ (int (*)()) hlink_compare);
+
+ for (from = 0; from < ndx_count; from++) {
+ for (file = FPTR(ndx_list[from]), idev = F_HL_IDEV(file), prev = -1;
+ from < ndx_count-1;
+ file = file_next, idev = idev_next, prev = ndx_list[from++])
+ {
+ file_next = FPTR(ndx_list[from+1]);
+ idev_next = F_HL_IDEV(file_next);
+ if (!LINKED(idev, idev_next))
+ break;
+ pool_free(hlink_pool, 0, idev);
+ if (prev < 0)
+ file->flags |= FLAG_HLINK_FIRST;
+ F_HL_PREV(file) = prev;
+ }
+ pool_free(hlink_pool, 0, idev);
+ if (prev < 0)
+ file->flags &= ~FLAG_HLINKED;
+ else {
+ file->flags |= FLAG_HLINK_LAST;
+ F_HL_PREV(file) = prev;
+ }
+ }