rpm/hardlink.diff

157 lines
4.6 KiB
Diff

Create first hard link file and keep open, write it at end
upstream commit e276991614fd127f21aba94946f81f22cb7e6b73
upstream commit 0afe0c3c6cba64d8b7adcdec6ed70f8d32961b58
upstream commit ef3ff412c33a71be6b3543a50c244377dff3d9e7
--- ./lib/fsm.c.orig 2017-10-05 10:04:56.977602149 +0000
+++ ./lib/fsm.c 2017-12-05 12:05:19.529973029 +0000
@@ -218,56 +218,76 @@ static int linkSane(FD_t wfd, const char
sb.st_dev == lsb.st_dev && sb.st_ino == lsb.st_ino);
}
-/** \ingroup payload
- * Create file from payload stream.
- * @return 0 on success
- */
-static int expandRegular(rpmfi fi, const char *dest, rpmpsm psm, int exclusive, int nodigest, int nocontent)
+static void wfd_close(FD_t *wfdp)
{
- FD_t wfd = NULL;
- int rc = 0;
+ if (wfdp && *wfdp) {
+ int myerrno = errno;
+ static int oneshot = 0;
+ static int flush_io = 0;
+ if (!oneshot) {
+ flush_io = rpmExpandNumeric("%{?_flush_io}");
+ oneshot = 1;
+ }
+ if (flush_io) {
+ int fdno = Fileno(*wfdp);
+ fsync(fdno);
+ }
+ Fclose(*wfdp);
+ *wfdp = NULL;
+ errno = myerrno;
+ }
+}
+static int wfd_open(FD_t *wfdp, const char *dest, int exclusive)
+{
+ int rc = 0;
/* Create the file with 0200 permissions (write by owner). */
{
mode_t old_umask = umask(0577);
- wfd = Fopen(dest, exclusive ? "wx.ufdio" : "a.ufdio");
+ *wfdp = Fopen(dest, exclusive ? "wx.ufdio" : "a.ufdio");
umask(old_umask);
/* If reopening, make sure the file is what we expect */
- if (!exclusive && wfd != NULL && !linkSane(wfd, dest)) {
+ if (!exclusive && *wfdp != NULL && !linkSane(*wfdp, dest)) {
rc = RPMERR_OPEN_FAILED;
goto exit;
}
}
- if (Ferror(wfd)) {
+ if (Ferror(*wfdp)) {
rc = RPMERR_OPEN_FAILED;
goto exit;
}
+ return 0;
+
+exit:
+ wfd_close(wfdp);
+ return rc;
+}
+
+/** \ingroup payload
+ * Create file from payload stream.
+ * @return 0 on success
+ */
+static int expandRegular(rpmfi fi, const char *dest, rpmpsm psm, int exclusive, int nodigest, int nocontent)
+{
+ FD_t wfd = NULL;
+ int rc;
+
+ rc = wfd_open(&wfd, dest, exclusive);
+ if (rc != 0)
+ goto exit;
+
if (!nocontent)
rc = rpmfiArchiveReadToFilePsm(fi, wfd, nodigest, psm);
+ wfd_close(&wfd);
exit:
- if (wfd) {
- int myerrno = errno;
- static int oneshot = 0;
- static int flush_io = 0;
- if (!oneshot) {
- flush_io = rpmExpandNumeric("%{?_flush_io}");
- oneshot = 1;
- }
- if (flush_io) {
- int fdno = Fileno(wfd);
- fsync(fdno);
- }
- Fclose(wfd);
- errno = myerrno;
- }
return rc;
}
static int fsmMkfile(rpmfi fi, const char *dest, rpmfiles files,
rpmpsm psm, int nodigest, int *setmeta,
- int * firsthardlink)
+ int * firsthardlink, FD_t *firstlinkfile)
{
int rc = 0;
int numHardlinks = rpmfiFNlink(fi);
@@ -276,7 +296,7 @@ static int fsmMkfile(rpmfi fi, const cha
/* Create first hardlinked file empty */
if (*firsthardlink < 0) {
*firsthardlink = rpmfiFX(fi);
- rc = expandRegular(fi, dest, psm, 1, nodigest, 1);
+ rc = wfd_open(firstlinkfile, dest, 1);
} else {
/* Create hard links for others */
char *fn = rpmfilesFN(files, *firsthardlink);
@@ -294,7 +314,8 @@ static int fsmMkfile(rpmfi fi, const cha
rc = expandRegular(fi, dest, psm, 1, nodigest, 0);
} else if (rpmfiArchiveHasContent(fi)) {
if (!rc)
- rc = expandRegular(fi, dest, psm, 0, nodigest, 0);
+ rc = rpmfiArchiveReadToFilePsm(fi, *firstlinkfile, nodigest, psm);
+ wfd_close(firstlinkfile);
*firsthardlink = -1;
} else {
*setmeta = 0;
@@ -861,6 +882,7 @@ int rpmPackageFilesInstall(rpmts ts, rpm
int nodigest = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOFILEDIGEST) ? 1 : 0;
int nofcaps = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCAPS) ? 1 : 0;
int firsthardlink = -1;
+ FD_t firstlinkfile = NULL;
int skip;
rpmFileAction action;
char *tid = NULL;
@@ -932,7 +954,7 @@ int rpmPackageFilesInstall(rpmts ts, rpm
if (S_ISREG(sb.st_mode)) {
if (rc == RPMERR_ENOENT) {
rc = fsmMkfile(fi, fpath, files, psm, nodigest,
- &setmeta, &firsthardlink);
+ &setmeta, &firsthardlink, &firstlinkfile);
}
} else if (S_ISDIR(sb.st_mode)) {
if (rc == RPMERR_ENOENT) {
@@ -970,7 +992,8 @@ int rpmPackageFilesInstall(rpmts ts, rpm
/* we skip the hard linked file containing the content */
/* write the content to the first used instead */
char *fn = rpmfilesFN(files, firsthardlink);
- rc = expandRegular(fi, fn, psm, 0, nodigest, 0);
+ rc = rpmfiArchiveReadToFilePsm(fi, firstlinkfile, nodigest, psm);
+ wfd_close(&firstlinkfile);
firsthardlink = -1;
free(fn);
}