return 0;
}
-static int seenHardLink(FileList fl, FileListRec flp)
+static int seenHardLink(FileList fl, FileListRec flp, rpm_ino_t *fileid)
{
for (FileListRec ilp = fl->fileList; ilp < flp; ilp++) {
if (isHardLink(flp, ilp)) {
+ *fileid = ilp - fl->fileList;
return 1;
}
}
int i;
uint32_t defaultalgo = PGPHASHALGO_MD5, digestalgo;
rpm_loff_t totalFileSize = 0;
+ dev_t brdev = 0;
/*
* See if non-md5 file digest algorithm is requested. If not
}
for (i = 0, flp = fl->fileList; i < fl->fileListRecsUsed; i++, flp++) {
+ rpm_ino_t fileid = flp - fl->fileList;
+
/* Merge duplicate entries. */
while (i < (fl->fileListRecsUsed - 1) &&
rstreq(flp->cpioPath, flp[1].cpioPath)) {
/* Skip files that were marked with %exclude. */
if (flp->flags & RPMFILE_EXCLUDE) continue;
+ if (brdev == 0 && flp->fl_dev != 0)
+ brdev = flp->fl_dev;
+ /*
+ * We could handle this quite easily but it can't happen without
+ * some very dirty tricks, so just error out for now...
+ */
+ if (brdev && flp->fl_dev && brdev != flp->fl_dev) {
+ rpmlog(RPMLOG_ERR, _("buildroot spans across filesystems\n"));
+ fl->processingFailed = 1;
+ }
+
/* Omit '/' and/or URL prefix, leave room for "./" prefix */
apathlen += (strlen(flp->cpioPath) - skipLen + (_addDotSlash ? 3 : 1));
}
/* Excludes and dupes have been filtered out by now. */
if (S_ISREG(flp->fl_mode)) {
- if (flp->fl_nlink == 1 || !seenHardLink(fl, flp)) {
+ if (flp->fl_nlink == 1 || !seenHardLink(fl, flp, &fileid)) {
totalFileSize += flp->fl_size;
}
}
headerPutUint32(h, RPMTAG_FILEDEVICES, &rdev, 1);
}
- { rpm_ino_t rino = (rpm_ino_t) flp->fl_ino;
+ /*
+ * To allow rpmbuild to work on filesystems with 64bit inodes numbers,
+ * remap them into 32bit integers based on filelist index, just
+ * preserving semantics for determining hardlinks.
+ * Start at 1 as inode zero as that could be considered as an error.
+ */
+ { rpm_ino_t rino = fileid + 1;
headerPutUint32(h, RPMTAG_FILEINODES, &rino, 1);
}
/* this check is pretty moot, rpmfi accessors check array bounds etc */
if (fi && i >= 0 && i < rpmfiFC(fi)) {
+ ino_t finalInode = rpmfiFInodeIndex(fi, i);
mode_t finalMode = rpmfiFModeIndex(fi, i);
dev_t finalRdev = rpmfiFRdevIndex(fi, i);
time_t finalMtime = rpmfiFMtimeIndex(fi, i);
if ((S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
&& st->st_nlink == 0)
st->st_nlink = 1;
+ st->st_ino = finalInode;
st->st_rdev = finalRdev;
st->st_mtime = finalMtime;
}