]> git.ipfire.org Git - thirdparty/rsync.git/commitdiff
Further improve non-empty-destination --link-dest behavior:
authorWayne Davison <wayned@samba.org>
Sat, 19 Jan 2013 17:52:56 +0000 (09:52 -0800)
committerWayne Davison <wayned@samba.org>
Sat, 19 Jan 2013 18:24:46 +0000 (10:24 -0800)
- Avoid relinking a file that is already linked correctly.
- Avoid trashing the stat buffer of an existing file in try_dests_reg().

generator.c

index e7bb90a4d1b114ea82428490cb8f64c78e34b57c..314122c3f222e207fae619b7e8ece4999d578e3f 100644 (file)
@@ -852,6 +852,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
                         char *cmpbuf, stat_x *sxp, int find_exact_for_existing,
                         int itemizing, enum logcode code)
 {
+       STRUCT_STAT real_st = sxp->st;
        int best_match = -1;
        int match_level = 0;
        int j = 0;
@@ -893,8 +894,12 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
 
        if (match_level == 3 && !copy_dest) {
                if (find_exact_for_existing) {
-                       if (do_unlink(fname) < 0 && errno != ENOENT)
+                       if (link_dest && real_st.st_dev == sxp->st.st_dev && real_st.st_ino == sxp->st.st_ino)
                                return -1;
+                       if (do_unlink(fname) < 0 && errno != ENOENT) {
+                               sxp->st = real_st;
+                               return -1;
+                       }
                }
 #ifdef SUPPORT_HARD_LINKS
                if (link_dest) {
@@ -918,15 +923,20 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
                return -2;
        }
 
-       if (find_exact_for_existing)
+       if (find_exact_for_existing) {
+               sxp->st = real_st;
                return -1;
+       }
 
        if (match_level >= 2) {
 #ifdef SUPPORT_HARD_LINKS
          try_a_copy: /* Copy the file locally. */
 #endif
-               if (!dry_run && copy_altdest_file(cmpbuf, fname, file) < 0)
+               if (!dry_run && copy_altdest_file(cmpbuf, fname, file) < 0) {
+                       if (find_exact_for_existing) /* Can get here via hard-link failure */
+                               sxp->st = real_st;
                        return -1;
+               }
                if (itemizing)
                        itemize(cmpbuf, file, ndx, 0, sxp, ITEM_LOCAL_CHANGE, 0, NULL);
                if (maybe_ATTRS_REPORT