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

Reply via email to