The ndx arg passed to increment_active_files() is now the unique,
[rsync/rsync.git] / hlink.c
diff --git a/hlink.c b/hlink.c
index 0918b69..28a1c74 100644 (file)
--- a/hlink.c
+++ b/hlink.c
@@ -33,14 +33,12 @@ extern int remove_source_files;
 extern int stdout_format_has_i;
 extern int maybe_ATTRS_REPORT;
 extern char *basis_dir[];
-extern struct file_list *the_file_list;
+extern struct file_list *cur_flist;
 
 #ifdef SUPPORT_HARD_LINKS
 
-alloc_pool_t hlink_pool;
-
 #define HASH_LOAD_LIMIT(size) ((size)*3/4)
-#define FPTR(i) (the_file_list->files[i])
+#define FPTR(i) (cur_flist->files[i])
 
 struct ihash_table {
        int32 size;
@@ -60,9 +58,9 @@ static struct ihash_table *ihash_create(int size)
        struct ihash_table *tbl;
 
        /* Pick a power of 2 that can hold the requested size. */
-       if (size & (size-1)) {
+       if (size & (size-1) || size < 16) {
                int req = size;
-               size = 32;
+               size = 16;
                while (size < req)
                        size *= 2;
        }
@@ -85,26 +83,18 @@ static void ihash_destroy(struct ihash_table *tbl)
 
 void init_hard_links(void)
 {
-       if (protocol_version >= 30) {
-               dev_tbl = ihash_create(16);
-               return;
-       }
-
-       if (!(hlink_pool = pool_create(HLINK_EXTENT, sizeof (struct idev),
-                                      out_of_memory, POOL_INTERN)))
-               out_of_memory("init_hard_links");
+       dev_tbl = ihash_create(16);
 }
 
 static void expand_ihash(struct ihash_table *tbl)
 {
-       struct idev_node *old_buckets;
+       struct idev_node *old_buckets = tbl->buckets;
        int size = tbl->size * 2;
        int i;
 
-       old_buckets = tbl->buckets;
        if (!(tbl->buckets = new_array(struct idev_node, size)))
                out_of_memory("ihash_create");
-       memset(tbl->buckets, 0, size * sizeof tbl->buckets[0]);
+       memset(tbl->buckets, 0, size * sizeof (struct idev_node));
        tbl->size = size;
        tbl->entries = 0;
 
@@ -208,30 +198,12 @@ void idev_destroy(void)
        ihash_destroy(dev_tbl);
 }
 
-/* This routine compares dev+inode info for protocols < 30. */
-static int hlink_compare_idev(int *int1, int *int2)
-{
-       struct file_struct *f1 = FPTR(*int1);
-       struct file_struct *f2 = FPTR(*int2);
-       struct idev *i1 = F_HL_IDEV(f1);
-       struct idev *i2 = F_HL_IDEV(f2);
-
-       if (i1->dev != i2->dev)
-               return i1->dev > i2->dev ? 1 : -1;
-
-       if (i1->ino != i2->ino)
-               return i1->ino > i2->ino ? 1 : -1;
-
-       return *int1 > *int2 ? 1 : -1;
-}
-
-/* This routine compares group numbers for protocols >= 30. */
 static int hlink_compare_gnum(int *int1, int *int2)
 {
        struct file_struct *f1 = FPTR(*int1);
        struct file_struct *f2 = FPTR(*int2);
-       int gnum1 = F_HL_GNUM(f1);
-       int gnum2 = F_HL_GNUM(f2);
+       int32 gnum1 = F_HL_GNUM(f1);
+       int32 gnum2 = F_HL_GNUM(f2);
 
        if (gnum1 != gnum2)
                return gnum1 > gnum2 ? 1 : -1;
@@ -239,46 +211,11 @@ static int hlink_compare_gnum(int *int1, int *int2)
        return *int1 > *int2 ? 1 : -1;
 }
 
-/* The match routine for protocols < 30. */
-static void match_idevs(int32 *ndx_list, int ndx_count)
-{
-       int32 from, prev;
-       struct file_struct *file, *file_next;
-       struct idev *idev, *idev_next;
-
-       qsort(ndx_list, ndx_count, sizeof ndx_list[0],
-            (int (*)()) hlink_compare_idev);
-
-       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 (idev->dev != idev_next->dev || idev->ino != idev_next->ino)
-                               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;
-               }
-       }
-}
-
-/* The match routine for protocols >= 30. */
 static void match_gnums(int32 *ndx_list, int ndx_count)
 {
        int32 from, prev;
        struct file_struct *file, *file_next;
-       int gnum, gnum_next;
+       int32 gnum, gnum_next;
 
        qsort(ndx_list, ndx_count, sizeof ndx_list[0],
             (int (*)()) hlink_compare_gnum);
@@ -314,23 +251,20 @@ void match_hard_links(void)
        int i, ndx_count = 0;
        int32 *ndx_list;
 
-       if (!(ndx_list = new_array(int32, the_file_list->count)))
+       if (!(ndx_list = new_array(int32, cur_flist->count)))
                out_of_memory("match_hard_links");
 
-       for (i = 0; i < the_file_list->count; i++) {
+       for (i = 0; i < cur_flist->count; i++) {
                if (F_IS_HLINKED(FPTR(i)))
                        ndx_list[ndx_count++] = i;
        }
 
-       if (ndx_count) {
-               if (protocol_version >= 30)
-                       match_gnums(ndx_list, ndx_count);
-               else {
-                       match_idevs(ndx_list, ndx_count);
-                       pool_destroy(hlink_pool);
-               }
-       }
+       if (ndx_count)
+               match_gnums(ndx_list, ndx_count);
+
        free(ndx_list);
+       if (protocol_version < 30)
+               idev_destroy();
 }
 
 static int maybe_hard_link(struct file_struct *file, int ndx,
@@ -351,7 +285,7 @@ static int maybe_hard_link(struct file_struct *file, int ndx,
                        file->flags |= FLAG_HLINK_DONE;
                        return 0;
                }
-               if (make_backups) {
+               if (make_backups > 0) {
                        if (!make_backup(fname))
                                return -1;
                } else if (robust_unlink(fname)) {
@@ -388,13 +322,13 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
        /* Is the previous link is not complete yet? */
        if (!(prev_file->flags & FLAG_HLINK_DONE)) {
                /* Is the previous link being transferred? */
-               if (prev_file->flags & FLAG_SENT) {
+               if (prev_file->flags & FLAG_FILE_SENT) {
                        /* Add ourselves to the list of files that will be
                         * updated when the transfer completes, and mark
                         * ourself as waiting for the transfer. */
                        F_HL_PREV(file) = F_HL_PREV(prev_file);
                        F_HL_PREV(prev_file) = ndx;
-                       file->flags |= FLAG_SENT;
+                       file->flags |= FLAG_FILE_SENT;
                        return 1;
                }
                return 0;