[SCM] The rsync repository. - branch master updated

Rsync CVS commit messages rsync-cvs at lists.samba.org
Fri Jun 13 17:06:13 MDT 2014


The branch, master has been updated
       via  ba43e88 Fix hard-link bugs when receiver isn't capable.
      from  ff08acd Added a flag to disable xattr hlink optimization.

;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit ba43e88527980718f99b680c3a3e3e2a3a97b6f3
Author: Wayne Davison <wayned at samba.org>
Date:   Fri Jun 13 15:58:26 2014 -0700

    Fix hard-link bugs when receiver isn't capable.
    
    If the receiving side cannot hard-link symlinks and/or special files
    (including devices) then we now properly handle incoming hard-linked
    items (creating separate identical items).

-----------------------------------------------------------------------

Summary of changes:
 NEWS        |    4 ++++
 flist.c     |    9 ++++++++-
 generator.c |   41 ++++++++++++++++++++---------------------
 hlink.c     |    2 +-
 4 files changed, 33 insertions(+), 23 deletions(-)


Changeset truncated at 500 lines:

diff --git a/NEWS b/NEWS
index 22766ce..5f2e738 100644
--- a/NEWS
+++ b/NEWS
@@ -59,6 +59,10 @@ Changes since 3.1.0:
       transfer failure.  This removal is flagged in the compatibility code, so
       if a better fix can be discovered, we have a way to flip it on again.
 
+    - Fixed a bug when the receiver is not configured to be able to hard link
+      symlimks/devices/special-file items but the sender sent some of these
+      items flagged as hard-linked.
+
     - We now generate a better error if the buffer overflows in do_mknod().
 
     - Fixed a problem reading more than 16 ACLs on some OSes.
diff --git a/flist.c b/flist.c
index fed0391..c24672e 100644
--- a/flist.c
+++ b/flist.c
@@ -948,7 +948,14 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
 	memcpy(bp, basename, basename_len);
 
 #ifdef SUPPORT_HARD_LINKS
-	if (xflags & XMIT_HLINKED)
+	if (xflags & XMIT_HLINKED
+#ifndef CAN_HARDLINK_SYMLINK
+	 && !S_ISLNK(mode)
+#endif
+#ifndef CAN_HARDLINK_SPECIAL
+	 && !IS_SPECIAL(mode) && !IS_DEVICE(mode)
+#endif
+	)
 		file->flags |= FLAG_HLINKED;
 #endif
 	file->modtime = (time_t)modtime;
diff --git a/generator.c b/generator.c
index 63399d3..91009a5 100644
--- a/generator.c
+++ b/generator.c
@@ -1511,7 +1511,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 				set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
 				if (itemizing)
 					itemize(fname, file, ndx, 0, &sx, 0, 0, NULL);
-#if defined SUPPORT_HARD_LINKS && defined CAN_HARDLINK_SYMLINK
+#ifdef SUPPORT_HARD_LINKS
 				if (preserve_hard_links && F_IS_HLINKED(file))
 					finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1);
 #endif
@@ -1537,7 +1537,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 				fnamecmp = fnamecmpbuf;
 			}
 		}
-		if (atomic_create(file, fname, sl, MAKEDEV(0, 0), &sx, statret == 0 ? DEL_FOR_SYMLINK : 0)) {
+		if (atomic_create(file, fname, sl, NULL, MAKEDEV(0, 0), &sx, statret == 0 ? DEL_FOR_SYMLINK : 0)) {
 			set_file_attrs(fname, file, NULL, NULL, 0);
 			if (itemizing) {
 				if (statret == 0 && !S_ISLNK(sx.st.st_mode))
@@ -1618,7 +1618,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 				fname, (int)file->mode,
 				(long)major(rdev), (long)minor(rdev));
 		}
-		if (atomic_create(file, fname, NULL, rdev, &sx, del_for_flag)) {
+		if (atomic_create(file, fname, NULL, NULL, rdev, &sx, del_for_flag)) {
 			set_file_attrs(fname, file, NULL, NULL, 0);
 			if (itemizing) {
 				itemize(fnamecmp, file, ndx, statret, &sx,
@@ -1923,11 +1923,11 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 }
 
 /* If we are replacing an existing hard link, symlink, device, or special file,
- * create a temp-name item and rename it into place.  Only a symlink or hard
- * link puts a non-NULL value into the lnk arg.  Only a device puts a non-0
- * value into the rdev arg.  Specify 0 for the del_for_flag if there is not a
- * file to replace.  This returns 1 on success and 0 on failure. */
-int atomic_create(struct file_struct *file, char *fname, const char *lnk,
+ * create a temp-name item and rename it into place.  A symlimk specifies slnk,
+ * a hard link specifies hlnk, otherwise we create a device based on rdev.
+ * Specify 0 for the del_for_flag if there is not a file to replace.  This
+ * returns 1 on success and 0 on failure. */
+int atomic_create(struct file_struct *file, char *fname, const char *slnk, const char *hlnk,
 		  dev_t rdev, stat_x *sxp, int del_for_flag)
 {
 	char tmpname[MAXPATHLEN];
@@ -1952,23 +1952,22 @@ int atomic_create(struct file_struct *file, char *fname, const char *lnk,
 
 	create_name = skip_atomic ? fname : tmpname;
 
-	if (lnk) {
+	if (slnk) {
 #ifdef SUPPORT_LINKS
-		if (S_ISLNK(file->mode)
-#ifdef SUPPORT_HARD_LINKS /* The first symlink in a hard-linked cluster is always created. */
-		 && (!F_IS_HLINKED(file) || file->flags & FLAG_HLINK_FIRST)
-#endif
-		 ) {
-			if (do_symlink(lnk, create_name) < 0) {
-				rsyserr(FERROR_XFER, errno, "symlink %s -> \"%s\" failed",
-					full_fname(create_name), lnk);
-				return 0;
-			}
-		} else
+		if (do_symlink(slnk, create_name) < 0) {
+			rsyserr(FERROR_XFER, errno, "symlink %s -> \"%s\" failed",
+				full_fname(create_name), slnk);
+			return 0;
+		}
+#else
+		return 0;
 #endif
+	} else if (hlnk) {
 #ifdef SUPPORT_HARD_LINKS
-		if (!hard_link_one(file, create_name, lnk, 0))
+		if (!hard_link_one(file, create_name, hlnk, 0))
 			return 0;
+#else
+		return 0;
 #endif
 	} else {
 		if (do_mknod(create_name, file->mode, rdev) < 0) {
diff --git a/hlink.c b/hlink.c
index df8e918..3b57898 100644
--- a/hlink.c
+++ b/hlink.c
@@ -231,7 +231,7 @@ static int maybe_hard_link(struct file_struct *file, int ndx,
 		}
 	}
 
-	if (atomic_create(file, fname, oldname, MAKEDEV(0, 0), sxp, statret == 0 ? DEL_FOR_FILE : 0)) {
+	if (atomic_create(file, fname, NULL, oldname, MAKEDEV(0, 0), sxp, statret == 0 ? DEL_FOR_FILE : 0)) {
 		if (itemizing) {
 			itemize(fname, file, ndx, statret, sxp,
 				ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,


-- 
The rsync repository.


More information about the rsync-cvs mailing list