--- 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 @@ -412,6 +412,8 @@ 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); + int nlink; + const int *links; if (XFA_SKIPPING(rpmfsGetAction(fs, fx))) return; @@ -481,7 +483,10 @@ static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfiles fi, int fx } } - rpmfilesSetFReplacedSize(fi, fx, 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) + rpmfilesSetFReplacedSize(fi, fx, rpmfilesFSize(otherFi, ofx)); } /** @@ -491,6 +496,7 @@ static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfiles fi, int fx static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfiles fi) { rpm_loff_t fixupSize = 0; + rpm_loff_t fileSize = 0; int i, j; rpmfs fs = rpmteGetFileStates(p); rpmfs otherFs; @@ -675,9 +681,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 = 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)); }