File hardlinks.diff of Package rpm

--- lib/rpmfiles.h.orig
+++ lib/rpmfiles.h
@@ -156,7 +156,7 @@ typedef rpmFlags rpmfiFlags;
 
 #define RPMFI_FLAGS_ERASE \
     (RPMFI_NOFILECLASS | RPMFI_NOFILELANGS | \
-     RPMFI_NOFILEMTIMES | RPMFI_NOFILERDEVS | RPMFI_NOFILEINODES | \
+     RPMFI_NOFILEMTIMES | RPMFI_NOFILERDEVS | \
      RPMFI_NOFILEVERIFYFLAGS)
 
 #define RPMFI_FLAGS_INSTALL \
--- lib/transaction.c.orig
+++ lib/transaction.c
@@ -231,11 +231,11 @@ static void rpmtsUpdateDSI(const rpmts ts, dev_t dev, const char *dirName,
 	dsi->bneeded += bneeded;
 	dsi->ineeded++;
 	if (prevSize) {
-	    dsi->bdelta += BLOCK_ROUND(prevSize, dsi->bsize);
+	    dsi->bdelta += BLOCK_ROUND(prevSize - 1, dsi->bsize);
 	    dsi->idelta++;
 	}
 	if (fixupSize) {
-	    dsi->bdelta += BLOCK_ROUND(fixupSize, dsi->bsize);
+	    dsi->bdelta += BLOCK_ROUND(fixupSize - 1, dsi->bsize);
 	    dsi->idelta++;
 	}
 
@@ -412,6 +412,9 @@ static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfiles fi, int fx
 {
     rpmfs fs = rpmteGetFileStates(p);
     int isCfgFile = ((rpmfilesFFlags(otherFi, ofx) | rpmfilesFFlags(fi, fx)) & RPMFILE_CONFIG);
+    rpm_loff_t otherFileSize;
+    int nlink;
+    const int *links;
 
     if (XFA_SKIPPING(rpmfsGetAction(fs, fx)))
 	return;
@@ -481,7 +484,15 @@ static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfiles fi, int fx
 	}
     }
 
-    rpmfilesSetFReplacedSize(fi, fx, rpmfilesFSize(otherFi, ofx));
+    otherFileSize = rpmfilesFSize(otherFi, ofx);
+
+    /* Only account for the last file of a hardlink set */
+    nlink = rpmfilesFLinks(otherFi, ofx, &links);
+    if (nlink > 1 && links[nlink - 1] != ofx)
+	otherFileSize = 0;
+
+    /* Add one to make sure the size is not zero */
+    rpmfilesSetFReplacedSize(fi, fx, otherFileSize + 1);
 }
 
 /**
@@ -506,6 +517,9 @@ static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi
 	rpmfileAttrs FFlags;
 	struct rpmffi_s * recs;
 	int numRecs;
+	rpm_loff_t fileSize;
+	int nlink;
+	const int *links;
 
 	if (XFA_SKIPPING(rpmfsGetAction(fs, i)))
 	    continue;
@@ -628,7 +642,8 @@ assert(otherFi != NULL);
 		break;
 
 	    /* Try to get the disk accounting correct even if a conflict. */
-	    fixupSize = rpmfilesFSize(otherFi, otherFileNum);
+	    /* Add one to make sure the size is not zero */
+	    fixupSize = rpmfilesFSize(otherFi, otherFileNum) + 1;
 
 	    if (rpmfilesConfigConflict(fi, i)) {
 		/* Here is an overlapped  pre-existing config file. */
@@ -675,9 +690,16 @@ assert(otherFi != NULL);
 	}
 	rpmfilesFree(otherFi);
 
+	fileSize = rpmfilesFSize(fi, i);
+	nlink = rpmfilesFLinks(fi, i, &links);
+	if (nlink > 1 && links[nlink - 1] != i) {
+	    /* Only account for the last file of a hardlink set */
+	    fileSize = 0;
+	    fixupSize = fixupSize ? 1 : 0;
+	}
 	/* Update disk space info for a file. */
 	rpmtsUpdateDSI(ts, fpEntryDev(fpc, fiFps), fpEntryDir(fpc, fiFps),
-		       rpmfilesFSize(fi, i), rpmfilesFReplacedSize(fi, i),
+		       fileSize, rpmfilesFReplacedSize(fi, i),
 		       fixupSize, rpmfsGetAction(fs, i));
 
     }