diff options
author | Wayne Davison <wayned@samba.org> | 2013-01-19 09:52:56 -0800 |
---|---|---|
committer | Wayne Davison <wayned@samba.org> | 2013-01-19 10:24:46 -0800 |
commit | c03bb3d181b300a30a45e043d5aa075af5e8e3f8 (patch) | |
tree | 72de7b4c36cfa82dc4e575bd961968e6f8f8db1d | |
parent | cee326436c5f2b41c2f10e4e1176cca0a786a368 (diff) | |
download | android_external_rsync-c03bb3d181b300a30a45e043d5aa075af5e8e3f8.tar.gz android_external_rsync-c03bb3d181b300a30a45e043d5aa075af5e8e3f8.tar.bz2 android_external_rsync-c03bb3d181b300a30a45e043d5aa075af5e8e3f8.zip |
Further improve non-empty-destination --link-dest behavior:
- Avoid relinking a file that is already linked correctly.
- Avoid trashing the stat buffer of an existing file in try_dests_reg().
-rw-r--r-- | generator.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/generator.c b/generator.c index e7bb90a4..314122c3 100644 --- a/generator.c +++ b/generator.c @@ -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 |