From 5f762af17c6e72e86e4710975dcdfd71fc5d1b07 Mon Sep 17 00:00:00 2001 From: chantra Date: Tue, 8 Feb 2022 18:24:12 -0800 Subject: [PATCH 19/30] [reflink] use `rpmpluginsCallFsmFileArchiveReader` to provide custom rpmfi As the plugin can now be responsible to provide an Archive Reader to `rpmPackageFilesInstall`, we also don't need to mutate the `RPMTAG_PAYLOADFORMAT` header in memory, removing some special-casing. --- lib/depends.c | 2 -- lib/fsm.c | 48 ++++++++++++++++++++++++++--------------------- plugins/reflink.c | 18 +++++++++++++----- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/lib/depends.c b/lib/depends.c index 8998afcd3..30234df3d 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -80,8 +80,6 @@ static rpmRC headerCheckPayloadFormat(Header h) { */ if (!payloadfmt) return rc; - if (rstreq(payloadfmt, "clon")) return rc; - if (!rstreq(payloadfmt, "cpio")) { char *nevra = headerGetAsString(h, RPMTAG_NEVRA); if (payloadfmt && rstreq(payloadfmt, "drpm")) { diff --git a/lib/fsm.c b/lib/fsm.c index 711f553d3..6972602e0 100644 --- a/lib/fsm.c +++ b/lib/fsm.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "rpmio/rpmio_internal.h" /* fdInit/FiniDigest */ #include "fsm.h" @@ -869,6 +868,24 @@ static rpmfi fsmIterFini(rpmfi fi, struct diriter_s *di) return rpmfiFree(fi); } +static int fiIterator(rpmPlugins plugins, FD_t payload, rpmfiles files, rpmfi *fi) +{ + rpmRC plugin_rc = rpmpluginsCallFsmFileArchiveReader(plugins, payload, files, fi); + switch (plugin_rc) { + case RPMRC_PLUGIN_CONTENTS: + if (*fi == NULL) + return RPMERR_BAD_MAGIC; + return RPMRC_OK; + case RPMRC_OK: + *fi = rpmfiNewArchiveReader(payload, files, RPMFI_ITER_READ_ARCHIVE); + if (*fi == NULL) + return RPMERR_BAD_MAGIC; + return RPMRC_OK; + default: + return RPMRC_FAIL; + } +} + int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, rpmpsm psm, char ** failedFile) { @@ -886,13 +903,6 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, struct filedata_s *fdata = xcalloc(fc, sizeof(*fdata)); struct filedata_s *firstlink = NULL; struct diriter_s di = { -1, -1 }; - Header h = rpmteHeader(te); - const char *payloadfmt = headerGetString(h, RPMTAG_PAYLOADFORMAT); - int cpio = 1; - - if (payloadfmt && rstreq(payloadfmt, "clon")) { - cpio = 0; - } /* transaction id used for temporary path suffix while installing */ rasprintf(&tid, ";%08x", (unsigned)rpmtsGetTid(ts)); @@ -927,12 +937,9 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, if (rc) goto exit; - if (cpio) { - fi = fsmIter(payload, files, - payload ? RPMFI_ITER_READ_ARCHIVE : RPMFI_ITER_FWD, &di); - } else { - fi = rpmfilesIter(files, RPMFI_ITER_FWD); - } + rc = fiIterator(plugins, payload, files, &fi); + if (rc) + goto exit; if (fi == NULL) { rc = RPMERR_BAD_MAGIC; @@ -956,7 +963,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, int mayopen = 0; int fd = -1; - if (!cpio && di.dirfd >= 0) + if (di.dirfd >= 0) fsmClose(&di.dirfd); rc = ensureDir(plugins, rpmfiDN(fi), 0, (fp->action == FA_CREATE), 0, &di.dirfd); @@ -1075,16 +1082,13 @@ setmeta: rc = fx; /* If all went well, commit files to final destination */ - if (cpio) { - fi = fsmIter(NULL, files, RPMFI_ITER_FWD, &di); - } else { - fi = rpmfilesIter(files, RPMFI_ITER_FWD); - } + fi = fsmIter(NULL, files, RPMFI_ITER_FWD, &di); + while (!rc && (fx = rpmfiNext(fi)) >= 0) { struct filedata_s *fp = &fdata[fx]; if (!fp->skip) { - if (!cpio && di.dirfd >= 0) + if (di.dirfd >= 0) fsmClose(&di.dirfd); if (!rc) rc = ensureDir(NULL, rpmfiDN(fi), 0, 0, 0, &di.dirfd); diff --git a/plugins/reflink.c b/plugins/reflink.c index 7dda06d8e..d5e6db27a 100644 --- a/plugins/reflink.c +++ b/plugins/reflink.c @@ -54,6 +54,7 @@ struct reflink_state_s { FD_t fd; rpmfiles files; inodeIndexHash inodeIndexes; + int transcoded; }; typedef struct reflink_state_s * reflink_state; @@ -116,12 +117,8 @@ static rpmRC reflink_psm_pre(rpmPlugin plugin, rpmte te) { break; } rpmlog(RPMLOG_DEBUG, _("reflink: *is* transcoded\n")); - Header h = rpmteHeader(te); + state->transcoded = 1; - /* replace/add header that main fsm.c can read */ - headerDel(h, RPMTAG_PAYLOADFORMAT); - headerPutString(h, RPMTAG_PAYLOADFORMAT, "clon"); - headerFree(h); state->files = rpmteFiles(te); /* tail of file contains offset_table, offset_checksums then magic */ if (Fseek(state->fd, -(sizeof(rpm_loff_t) * 2 + sizeof(extents_magic_t)), SEEK_END) < 0) { @@ -350,10 +347,21 @@ static rpmRC reflink_fsm_file_install(rpmPlugin plugin, rpmfi fi, const char* pa return RPMRC_OK; } +static rpmRC reflink_fsm_file_archive_reader(rpmPlugin plugin, FD_t payload, + rpmfiles files, rpmfi *fi) { + reflink_state state = rpmPluginGetData(plugin); + if(state->transcoded) { + *fi = rpmfilesIter(files, RPMFI_ITER_FWD); + return RPMRC_PLUGIN_CONTENTS; + } + return RPMRC_OK; +} + struct rpmPluginHooks_s reflink_hooks = { .init = reflink_init, .cleanup = reflink_cleanup, .psm_pre = reflink_psm_pre, .psm_post = reflink_psm_post, .fsm_file_install = reflink_fsm_file_install, + .fsm_file_archive_reader = reflink_fsm_file_archive_reader, }; -- 2.35.1