File touch_backport.diff of Package rpm.27835

--- ./lib/fsm.c.orig	2020-12-09 10:51:09.641203826 +0000
+++ ./lib/fsm.c	2020-12-09 10:51:14.185191380 +0000
@@ -894,12 +894,12 @@ int rpmPackageFilesInstall(rpmts ts, rpm
 
 	action = rpmfsGetAction(fs, rpmfiFX(fi));
 	skip = XFA_SKIPPING(action);
-	suffix = S_ISDIR(rpmfiFMode(fi)) ? NULL : tid;
 	if (action != FA_TOUCH) {
-	    fpath = fsmFsPath(fi, suffix);
+	    suffix = S_ISDIR(rpmfiFMode(fi)) ? NULL : tid;
 	} else {
-	    fpath = fsmFsPath(fi, "");
+	    suffix = NULL;
 	}
+	fpath = fsmFsPath(fi, suffix);
 
 	/* Remap file perms, owner, and group. */
 	rc = rpmfiStat(fi, 1, &sb);
@@ -930,9 +930,20 @@ int rpmPackageFilesInstall(rpmts ts, rpm
 	    if (!suffix) {
 		rc = fsmVerify(fpath, fi);
 	    } else {
-		rc = (action == FA_TOUCH) ? 0 : RPMERR_ENOENT;
+		rc = RPMERR_ENOENT;
+	    }
+
+	    /* See if the file was removed while our attention was elsewhere */
+	    if (rc == RPMERR_ENOENT && action == FA_TOUCH) {
+		rpmlog(RPMLOG_DEBUG, "file %s vanished unexpectedly\n", fpath);
+		action = FA_CREATE;
+		fsmDebug(fpath, action, &sb);
 	    }
 
+	    /* When touching we don't need any of this... */
+	    if (action == FA_TOUCH)
+		goto touch;
+
             if (S_ISREG(sb.st_mode)) {
 		if (rc == RPMERR_ENOENT) {
 		    rc = fsmMkfile(fi, fpath, files, psm, nodigest,
@@ -966,11 +977,14 @@ int rpmPackageFilesInstall(rpmts ts, rpm
                 if (!IS_DEV_LOG(fpath))
                     rc = RPMERR_UNKNOWN_FILETYPE;
             }
+
+touch:
 	    /* Set permissions, timestamps etc for non-hardlink entries */
 	    if (!rc && setmeta) {
 		rc = fsmSetmeta(fpath, fi, plugins, action, &sb, nofcaps);
 	    }
         } else if (firsthardlink >= 0 && rpmfiArchiveHasContent(fi)) {
+	    /* On FA_TOUCH no hardlinks are created thus this is skipped. */
 	    /* we skip the hard linked file containing the content */
 	    /* write the content to the first used instead */
 	    char *fn = rpmfilesFN(files, firsthardlink);
@@ -983,7 +997,7 @@ int rpmPackageFilesInstall(rpmts ts, rpm
         if (rc) {
             if (!skip) {
                 /* XXX only erase if temp fn w suffix is in use */
-                if (suffix && (action != FA_TOUCH)) {
+                if (suffix) {
 		    (void) fsmRemove(fpath, sb.st_mode);
                 }
                 errno = saveerrno;
--- ./lib/transaction.c.orig	2020-12-09 10:39:50.003059866 +0000
+++ ./lib/transaction.c	2020-12-09 10:51:14.185191380 +0000
@@ -483,13 +483,6 @@ static void handleInstInstalledFile(cons
 	rpmfsSetAction(fs, fx, action);
     }
 
-    /* Skip already existing files - if 'minimize_writes' is set. */
-    if ((!isCfgFile) && (rpmfsGetAction(fs, fx) == FA_UNKNOWN)  && ts->min_writes) {
-	if (rpmfileContentsEqual(otherFi, ofx, fi, fx)) {
-	   rpmfsSetAction(fs, fx, FA_TOUCH);
-	}
-    }
-
     otherFileSize = rpmfilesFSize(otherFi, ofx);
 
     /* Only account for the last file of a hardlink set */
@@ -499,6 +492,16 @@ static void handleInstInstalledFile(cons
 
     /* Add one to make sure the size is not zero */
     rpmfilesSetFReplacedSize(fi, fx, otherFileSize + 1);
+
+    /* Just touch already existing files if minimize_writes is enabled */
+    if (ts->min_writes) {
+	if ((!isCfgFile) && (rpmfsGetAction(fs, fx) == FA_UNKNOWN)) {
+	    /* XXX fsm can't handle FA_TOUCH of hardlinked files */
+	    int nolinks = (nlink == 1 && rpmfilesFNlink(fi, fx) == 1);
+	    if (nolinks && rpmfileContentsEqual(otherFi, ofx, fi, fx))
+	       rpmfsSetAction(fs, fx, FA_TOUCH);
+	}
+    }
 }
 
 /**
openSUSE Build Service is sponsored by