From 62c9e6b3a54f147629497a2bc791acac60b5668b Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Tue, 17 Feb 2004 23:13:10 +0000 Subject: [PATCH] Moved the EXDEV handling into robust_rename(). --- backup.c | 40 ++++------------------------------------ rsync.c | 24 ++++++++---------------- util.c | 35 +++++++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 62 deletions(-) diff --git a/backup.c b/backup.c index 35568d94..2078861b 100644 --- a/backup.c +++ b/backup.c @@ -130,42 +130,10 @@ failure: /* robustly move a file, creating new directory structures if necessary */ static int robust_move(char *src, char *dst) { - int keep_trying = 4; - int keep_path_extfs = 0; - int failed; - - while (keep_trying) { - if (keep_path_extfs) { - failed = copy_file(src, dst, 0755); - if (!failed) - do_unlink(src); - } else - failed = robust_rename(src, dst); - - if (failed) { - if (verbose > 2) { - rprintf(FERROR, "robust_move failed: %s(%d)\n", - strerror(errno), errno); - } - switch (errno) { - case EXDEV: /* external filesystem */ - keep_path_extfs = 1; - keep_trying--; - break; - case ENOENT: /* no directory to write to */ - if (make_bak_dir(dst) < 0) - keep_trying = 0; - else - keep_trying--; - break; - default: - keep_trying = 0; - break; - } - } else - keep_trying = 0; - } - return !failed; + if (robust_rename(src, dst, 0755) != 0 || errno != ENOENT + || make_bak_dir(dst) < 0 || robust_rename(src, dst, 0755) != 0) + return -1; + return 0; } diff --git a/rsync.c b/rsync.c index 78fedab6..cf310e9c 100644 --- a/rsync.c +++ b/rsync.c @@ -158,7 +158,7 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st, change_gid = preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid; if (change_uid || change_gid) { - if (verbose > 2 && !dry_run) { + if (verbose > 2) { if (change_uid) { rprintf(FINFO, "set uid of %s from %ld to %ld\n", @@ -231,25 +231,17 @@ void sig_int(void) and ownership */ void finish_transfer(char *fname, char *fnametmp, struct file_struct *file) { + int ret; + if (make_backups && !make_backup(fname)) return; /* move tmp file over real file */ - if (robust_rename(fnametmp,fname) != 0) { - if (errno == EXDEV) { - /* rename failed on cross-filesystem link. - Copy the file instead. */ - if (copy_file(fnametmp,fname, file->mode & INITACCESSPERMS)) { - rprintf(FERROR, "copy %s -> \"%s\": %s\n", - full_fname(fnametmp), fname, - strerror(errno)); - } else { - set_perms(fname,file,NULL,0); - } - } else { - rprintf(FERROR,"rename %s -> \"%s\": %s\n", - full_fname(fnametmp), fname, strerror(errno)); - } + ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS); + if (ret != 0) { + rprintf(FERROR, "%s %s -> \"%s\": %s\n", + ret == -2 ? "copy" : "rename", + full_fname(fnametmp), fname, strerror(errno)); do_unlink(fnametmp); } else { set_perms(fname,file,NULL,0); diff --git a/util.c b/util.c index fd01283a..cb47c2a1 100644 --- a/util.c +++ b/util.c @@ -353,18 +353,33 @@ int robust_unlink(char *fname) #endif } -int robust_rename(char *from, char *to) +/* Returns 0 on success, -1 on most errors, and -2 if we got an error + * trying to copy the file across file systems. */ +int robust_rename(char *from, char *to, int mode) { -#ifndef ETXTBSY - return do_rename(from, to); -#else - int rc = do_rename(from, to); - if (rc == 0 || errno != ETXTBSY) - return rc; - if (robust_unlink(to) != 0) - return -1; - return do_rename(from, to); + int tries = 4; + + while (tries--) { + if (do_rename(from, to) == 0) + return 0; + + switch (errno) { +#ifdef ETXTBSY + case ETXTBSY: + if (robust_unlink(to) != 0) + return -1; + break; #endif + case EXDEV: + if (copy_file(from, to, mode) != 0) + return -2; + do_unlink(from); + return 0; + default: + return -1; + } + } + return -1; } -- 2.34.1