X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/c905bf37f6a6a248944c63ce85882f78b5255871..121bfb2b4d9df88bfbc9917209842bb8d9d17e22:/hlink.c diff --git a/hlink.c b/hlink.c index 0918b691..28a1c74f 100644 --- 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;