James,
Applied the patch, and it fails spectacularly :^)
Check this out:
ls -l
drwxr-xr-x 3 root root 1024 Dec 10 1999 .automount
-rw------- 25192 root root 241 Mar 28 1999 .bash_history
-rw-r--r-- 25292 root root 553 Mar 28 1999 auto.net
drwxr-xr-x 2 root root 2048 Dec 29 1999 bin
25192 Hard links to .bash_history? Not by a long shot. Should read:
drwxr-xr-x 3 root root 1024 Dec 10 1999 .automount
-rw------- 1 root root 241 Mar 28 1999 .bash_history
-rw-r--r-- 1 root root 553 Mar 28 1999 auto.net
drwxr-xr-x 2 root root 2048 Dec 29 1999 bin
The idea seems good, but would require that the same version of rsync be
on both machines. Have to be a new protocol, with a switch to talk to
earlier stuff.
Jim Delahanty
James Gritton wrote:
>
> This statement in the man page has bothered me for some time:
>
> | -H, --hard-links
> | ...
> | This option can be quite slow, so only use it if you need it.
>
> Taking a look at the code, it's clear that every single file is checked to
> see if it's a hard link to an existing file. In particular, the stat field
> nlink is never even looked at.
>
> I've patched the program to only run the expensive hard-link check on files
> where stat returns nlink > 1. This keeps the same behavior and
> significantly reduces memory usage (down from 30MB to 20MB for copying my
> /usr partition).
>
> - James Gritton
> [EMAIL PROTECTED]
>
> --- rsync.h.orig Sat Aug 19 07:10:39 2000
> +++ rsync.h Thu Sep 7 13:27:30 2000
> @@ -297,6 +297,7 @@
> dev_t rdev;
> uid_t uid;
> gid_t gid;
> + nlink_t nlink;
> char *basename;
> char *dirname;
> char *basedir;
> @@ -317,6 +318,7 @@
> struct file_list {
> int count;
> int malloced;
> + int hlink_count;
> struct file_struct **files;
> struct string_area *string_area;
> };
> --- flist.c.orig Sat Aug 19 07:10:39 2000
> +++ flist.c Thu Sep 7 14:10:29 2000
> @@ -299,8 +299,8 @@
>
> #if SUPPORT_HARD_LINKS
> if (preserve_hard_links && S_ISREG(file->mode)) {
> - write_int(f,(int)file->dev);
> - write_int(f,(int)file->inode);
> + write_int(f,file->nlink > 1 ? (int)file->dev : 0);
> + write_int(f,file->nlink > 1 ? (int)file->inode : 0);
> }
> #endif
>
> @@ -554,6 +554,10 @@
> #ifdef HAVE_ST_RDEV
> file->rdev = st.st_rdev;
> #endif
> +#if SUPPORT_HARD_LINKS
> + if (preserve_hard_links && S_ISREG(st.st_mode))
> + file->nlink = st.st_nlink;
> +#endif
>
> #if SUPPORT_LINKS
> if (S_ISLNK(st.st_mode)) {
> @@ -870,6 +874,9 @@
>
> flist->count=0;
> flist->malloced=1000;
> +#if SUPPORT_HARD_LINKS
> + flist->hlink_count=0;
> +#endif
> flist->files = (struct file_struct **)malloc(sizeof(flist->files[0])*
> flist->malloced);
> if (!flist->files)
> @@ -893,8 +900,13 @@
>
> receive_file_entry(&flist->files[i],flags,f);
>
> - if (S_ISREG(flist->files[i]->mode))
> + if (S_ISREG(flist->files[i]->mode)) {
> stats.total_size += flist->files[i]->length;
> +#if SUPPORT_HARD_LINKS
> + if (preserve_hard_links && flist->files[i]->inode)
> + flist->hlink_count++;
> +#endif
> + }
>
> flist->count++;
>
> --- hlink.c.orig Mon Mar 15 14:23:11 1999
> +++ hlink.c Thu Sep 7 14:10:19 2000
> @@ -46,23 +46,26 @@
> void init_hard_links(struct file_list *flist)
> {
> #if SUPPORT_HARD_LINKS
> - int i;
> - if (flist->count < 2) return;
> + int i, j;
> + if (flist->hlink_count < 2) return;
>
> if (hlink_list) free(hlink_list);
>
> if (!(hlink_list =
> - (struct file_struct *)malloc(sizeof(hlink_list[0])*flist->count)))
> + (struct file_struct
>*)malloc(sizeof(hlink_list[0])*flist->hlink_count)))
> out_of_memory("init_hard_links");
>
> - for (i = 0; i < flist->count; i++)
> - memcpy(&hlink_list[i], flist->files[i], sizeof(hlink_list[0]));
> + for (i = j = 0; i < flist->count; i++) {
> + if (S_ISREG(flist->files[i]->mode) && flist->files[i]->inode)
> + memcpy(&hlink_list[j++], flist->files[i],
> + sizeof(hlink_list[0]));
> + }
>
> - qsort(hlink_list,flist->count,
> + qsort(hlink_list,flist->hlink_count,
> sizeof(hlink_list[0]),
> (int (*)())hlink_compare);
>
> - hlink_count=flist->count;
> + hlink_count=flist->hlink_count;
> #endif
> }
>
> @@ -74,7 +77,7 @@
> int low=0,high=hlink_count-1;
> int ret=0;
>
> - if (!hlink_list || !S_ISREG(file->mode)) return 0;
> + if (!hlink_list || !S_ISREG(file->mode) || !file->inode) return 0;
>
> while (low != high) {
> int mid = (low+high)/2;
S/MIME Cryptographic Signature