Improve hardlink handling in the disk space calculation
Before this commit, rpm simply did not take hardlinks into account when calculating disk space requirements. This made it fail spectaculary for packages that contain a high number of hardlinks, like glibc-locale. We now "bind" the file size to the last hardlink member. This is still not 100% correct as the last file may not get installed in some cases or only the last file may be replaced. But it is still much better than what rpm did before.
This commit is contained in:
parent
791cf86205
commit
ae0347cfb2
|
@ -156,7 +156,7 @@ typedef rpmFlags rpmfiFlags;
|
||||||
|
|
||||||
#define RPMFI_FLAGS_ERASE \
|
#define RPMFI_FLAGS_ERASE \
|
||||||
(RPMFI_NOFILECLASS | RPMFI_NOFILELANGS | \
|
(RPMFI_NOFILECLASS | RPMFI_NOFILELANGS | \
|
||||||
RPMFI_NOFILEMTIMES | RPMFI_NOFILERDEVS | RPMFI_NOFILEINODES | \
|
RPMFI_NOFILEMTIMES | RPMFI_NOFILERDEVS | \
|
||||||
RPMFI_NOFILEVERIFYFLAGS)
|
RPMFI_NOFILEVERIFYFLAGS)
|
||||||
|
|
||||||
#define RPMFI_FLAGS_INSTALL \
|
#define RPMFI_FLAGS_INSTALL \
|
||||||
|
|
|
@ -412,6 +412,9 @@ static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfiles fi, int fx
|
||||||
{
|
{
|
||||||
rpmfs fs = rpmteGetFileStates(p);
|
rpmfs fs = rpmteGetFileStates(p);
|
||||||
int isCfgFile = ((rpmfilesFFlags(otherFi, ofx) | rpmfilesFFlags(fi, fx)) & RPMFILE_CONFIG);
|
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)))
|
if (XFA_SKIPPING(rpmfsGetAction(fs, fx)))
|
||||||
return;
|
return;
|
||||||
|
@ -481,8 +484,15 @@ static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfiles fi, int fx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 */
|
/* Add one to make sure the size is not zero */
|
||||||
rpmfilesSetFReplacedSize(fi, fx, rpmfilesFSize(otherFi, ofx) + 1);
|
rpmfilesSetFReplacedSize(fi, fx, otherFileSize + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -507,6 +517,9 @@ static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi
|
||||||
rpmfileAttrs FFlags;
|
rpmfileAttrs FFlags;
|
||||||
struct rpmffi_s * recs;
|
struct rpmffi_s * recs;
|
||||||
int numRecs;
|
int numRecs;
|
||||||
|
rpm_loff_t fileSize;
|
||||||
|
int nlink;
|
||||||
|
const int *links;
|
||||||
|
|
||||||
if (XFA_SKIPPING(rpmfsGetAction(fs, i)))
|
if (XFA_SKIPPING(rpmfsGetAction(fs, i)))
|
||||||
continue;
|
continue;
|
||||||
|
@ -677,9 +690,16 @@ assert(otherFi != NULL);
|
||||||
}
|
}
|
||||||
rpmfilesFree(otherFi);
|
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. */
|
/* Update disk space info for a file. */
|
||||||
rpmtsUpdateDSI(ts, fpEntryDev(fpc, fiFps), fpEntryDir(fpc, fiFps),
|
rpmtsUpdateDSI(ts, fpEntryDev(fpc, fiFps), fpEntryDir(fpc, fiFps),
|
||||||
rpmfilesFSize(fi, i), rpmfilesFReplacedSize(fi, i),
|
fileSize, rpmfilesFReplacedSize(fi, i),
|
||||||
fixupSize, rpmfsGetAction(fs, i));
|
fixupSize, rpmfsGetAction(fs, i));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue