[patch] Make robust_rename() handle EXDEV.

Jason M. Felice jfelice at cronosys.com
Tue Feb 17 15:28:20 GMT 2004


All callers of robust_rename() call copy_file() if EXDEV is received.  This
patch moves the copy_file() call into robust_rename().

Patch Summary:

    -12  +1    backup.c
    -15  +2    rsync.c
    -9   +33   util.c
-------------- next part --------------
patchwork diff util.c
--- util.c	2004-02-17 09:58:44.000000000 -0500
+++ util.c	2004-02-17 10:21:22.000000000 -0500
@@ -355,16 +355,40 @@
 
 int robust_rename(char *from, char *to)
 {
-#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 do_copy = 0, tries = 4, rc;
+	STRUCT_STAT st;
+	while (tries--) {
+		if (do_copy) {
+			rc = copy_file(from, to, st.st_mode);
+			if (rc == 0) {
+				do_unlink(from);
+			}
+		} else {
+			rc = do_rename(from, to);
+		}
+
+		if (rc == 0)
+			return 0;
+
+		switch (errno) {
+#ifdef ETXTBSY
+		case ETXTBSY:
+			if (robust_unlink(to) != 0)
+				return -1;
+			break;
 #endif
+		case EXDEV:
+			if (do_stat(from, &st) == -1) {
+				st.st_mode = 0755;
+			}
+			do_copy = 1;
+			break;
+
+		default:
+			return -1;
+		}
+	}
+	return -1;
 }
 
 
patchwork diff rsync.c
--- rsync.c	2004-02-17 09:58:48.000000000 -0500
+++ rsync.c	2004-02-17 10:13:31.000000000 -0500
@@ -236,21 +236,8 @@
 
 	/* 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));
-		}
-		do_unlink(fnametmp);
+		rprintf(FERROR,"rename %s -> \"%s\": %s\n",
+			full_fname(fnametmp), fname, strerror(errno));
 	} else {
 		set_perms(fname,file,NULL,0);
 	}
patchwork diff backup.c
--- backup.c	2004-02-17 09:58:51.000000000 -0500
+++ backup.c	2004-02-17 10:12:15.000000000 -0500
@@ -131,27 +131,16 @@
 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);
-
+		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;


More information about the rsync mailing list