From 4527e1db7923906ab174dcc930abcb5d96d01b64 Mon Sep 17 00:00:00 2001 From: longpanda Date: Tue, 23 Jan 2024 09:08:23 +0800 Subject: [PATCH] Add support for FreeBSD 14.0 --- INSTALL/ventoy/ventoy_unix.cpio | Bin 130560 -> 131584 bytes .../geom_ventoy_ko/14.x/32/geom_ventoy.ko.xz | Bin 8124 -> 8656 bytes .../geom_ventoy_ko/14.x/64/geom_ventoy.ko.xz | Bin 7908 -> 7900 bytes .../14.x/sys/geom/ventoy/g_ventoy.c | 1243 +++++++++++++++++ .../14.x/sys/geom/ventoy/g_ventoy.h | 147 ++ .../sys/modules/geom/geom_ventoy/Makefile | 8 + 6 files changed, 1398 insertions(+) create mode 100644 Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.c create mode 100644 Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.h create mode 100644 Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/modules/geom/geom_ventoy/Makefile diff --git a/INSTALL/ventoy/ventoy_unix.cpio b/INSTALL/ventoy/ventoy_unix.cpio index 7583906586c5f4463396ea2a8a6b9d1758e1e895..630a5af643c6fcadbd7c816c06d4b1f9092bdc82 100644 GIT binary patch delta 19313 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 diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/32/geom_ventoy.ko.xz index 806d4cc1d017b9c9d6223b668a64a7bf9ac02456..938a3623200e61df7af37b92901c3a260bf5c2e2 100644 GIT binary patch literal 8656 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 W8EzK*)vz<*?Pg+NU|?X3i~<0?Jetn{ literal 8124 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 diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/14.x/64/geom_ventoy.ko.xz index cdcdd12e5bc57a51b554589546d5ef70ab646bf5..69a736705be619a0db624f161040be70f4b1debd 100644 GIT binary patch literal 7900 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 SZhrW@@ksh_CXggcWE21&Qc$!2 diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.c new file mode 100644 index 00000000..d12a7194 --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.c @@ -0,0 +1,1243 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FEATURE(geom_ventoy, "GEOM ventoy support"); + +static MALLOC_DEFINE(M_VENTOY, "ventoy_data", "GEOM_VENTOY Data"); + +SYSCTL_DECL(_kern_geom); +static SYSCTL_NODE(_kern_geom, OID_AUTO, ventoy, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, + "GEOM_VENTOY stuff"); +static u_int g_ventoy_debug = 0; +SYSCTL_UINT(_kern_geom_ventoy, OID_AUTO, debug, CTLFLAG_RWTUN, &g_ventoy_debug, 0, + "Debug level"); + +extern int resource_string_value(const char *name, int unit, const char *resname, const char **result); +extern int resource_int_value(const char *name, int unit, const char *resname, int *result); + +static int g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force); +static int g_ventoy_destroy_geom(struct gctl_req *req, struct g_class *mp, + struct g_geom *gp); + +static g_taste_t g_ventoy_taste; +static g_ctl_req_t g_ventoy_config; +static g_dumpconf_t g_ventoy_dumpconf; + +static char g_ventoy_disk_uuid[64]; +static bool g_ventoy_tasted = false; +static off_t g_ventoy_disk_size = 0; +static off_t g_disk_map_start = 0; +static off_t g_disk_map_end = 0; +static int g_ventoy_remount = 0; + +struct g_ventoy_map g_ventoy_map_data __attribute__((aligned (4096))) = +{ + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 }, + { 0, 0, 0, 0 }, + 0, 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { { 0, 0 } }, + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 } +}; + +struct g_class g_ventoy_class = { + .name = G_VENTOY_CLASS_NAME, + .version = G_VERSION, + .ctlreq = g_ventoy_config, + .taste = g_ventoy_taste, + .destroy_geom = g_ventoy_destroy_geom +}; + + +/* + * Greatest Common Divisor. + */ +static u_int +gcd(u_int a, u_int b) +{ + u_int c; + + while (b != 0) { + c = a; + a = b; + b = (c % b); + } + return (a); +} + +/* + * Least Common Multiple. + */ +static u_int +lcm(u_int a, u_int b) +{ + + return ((a * b) / gcd(a, b)); +} + +/* + * Return the number of valid disks. + */ +static u_int +g_ventoy_nvalid(struct g_ventoy_softc *sc) +{ + u_int no; + struct g_ventoy_disk *disk; + + sx_assert(&sc->sc_disks_lock, SA_LOCKED); + + no = 0; + TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { + if (disk->d_consumer != NULL) + no++; + } + + return (no); +} + +static void +g_ventoy_remove_disk(struct g_ventoy_disk *disk) +{ + struct g_consumer *cp; + struct g_ventoy_softc *sc; + + g_topology_assert(); + KASSERT(disk->d_consumer != NULL, ("Non-valid disk in %s.", __func__)); + sc = disk->d_softc; + cp = disk->d_consumer; + + if (!disk->d_removed) { + G_VENTOY_DEBUG(0, "Disk %s removed from %s.", + cp->provider->name, sc->sc_name); + disk->d_removed = 1; + } + + if (sc->sc_provider != NULL) { + G_VENTOY_DEBUG(0, "Device %s deactivated.", + sc->sc_provider->name); + g_wither_provider(sc->sc_provider, ENXIO); + sc->sc_provider = NULL; + } + + if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) + return; + disk->d_consumer = NULL; + g_detach(cp); + g_destroy_consumer(cp); + /* If there are no valid disks anymore, remove device. */ + if (LIST_EMPTY(&sc->sc_geom->consumer)) + g_ventoy_destroy(sc, 1); +} + +static void +g_ventoy_orphan(struct g_consumer *cp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_geom *gp; + + g_topology_assert(); + gp = cp->geom; + sc = gp->softc; + if (sc == NULL) + return; + + disk = cp->private; + if (disk == NULL) /* Possible? */ + return; + g_ventoy_remove_disk(disk); +} + +static int +g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) +{ + struct g_consumer *cp1, *cp2, *tmp; + struct g_ventoy_disk *disk; + struct g_geom *gp; + struct g_ventoy_softc *sc; + int error; + + if (dw > 0) /* readonly */ + return (EPERM); + + g_topology_assert(); + gp = pp->geom; + sc = gp->softc; + + if (g_ventoy_remount) + { + de = 0; + } + else + { + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + } + + sx_slock(&sc->sc_disks_lock); + LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { + error = g_access(cp1, dr, dw, de); + if (error != 0) + goto fail; + disk = cp1->private; + if (cp1->acr == 0 && cp1->acw == 0 && cp1->ace == 0 && + disk->d_removed) { + g_ventoy_remove_disk(disk); /* May destroy geom. */ + } + } + sx_sunlock(&sc->sc_disks_lock); + return (0); + +fail: + sx_sunlock(&sc->sc_disks_lock); + LIST_FOREACH(cp2, &gp->consumer, consumer) { + if (cp1 == cp2) + break; + g_access(cp2, -dr, -dw, -de); + } + return (error); +} + +static void +g_ventoy_candelete(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + int val; + + sc = bp->bio_to->geom->softc; + sx_assert(&sc->sc_disks_lock, SX_LOCKED); + TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { + if (!disk->d_removed && disk->d_candelete) + break; + } + val = disk != NULL; + g_handleattr(bp, "GEOM::candelete", &val, sizeof(val)); +} + +static void +g_ventoy_kernel_dump(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct bio *cbp; + struct g_kerneldump *gkd; + + sc = bp->bio_to->geom->softc; + gkd = (struct g_kerneldump *)bp->bio_data; + TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { + if (disk->d_start <= gkd->offset && + disk->d_end > gkd->offset) + break; + } + if (disk == NULL) { + g_io_deliver(bp, EOPNOTSUPP); + return; + } + + gkd->offset -= disk->d_start; + if (gkd->length > disk->d_end - disk->d_start - gkd->offset) + gkd->length = disk->d_end - disk->d_start - gkd->offset; + cbp = g_clone_bio(bp); + if (cbp == NULL) { + g_io_deliver(bp, ENOMEM); + return; + } + cbp->bio_done = g_std_done; + g_io_request(cbp, disk->d_consumer); + G_VENTOY_DEBUG(1, "Kernel dump will go to %s.", + disk->d_consumer->provider->name); +} + +static void +g_ventoy_done(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct bio *pbp; + + pbp = bp->bio_parent; + sc = pbp->bio_to->geom->softc; + mtx_lock(&sc->sc_completion_lock); + if (pbp->bio_error == 0) + pbp->bio_error = bp->bio_error; + pbp->bio_completed += bp->bio_completed; + pbp->bio_inbed++; + if (pbp->bio_children == pbp->bio_inbed) { + mtx_unlock(&sc->sc_completion_lock); + g_io_deliver(pbp, pbp->bio_error); + } else + mtx_unlock(&sc->sc_completion_lock); + g_destroy_bio(bp); +} + +static void +g_ventoy_flush(struct g_ventoy_softc *sc, struct bio *bp) +{ + struct bio_queue_head queue; + struct g_consumer *cp; + struct bio *cbp; + struct g_ventoy_disk *disk; + + sx_assert(&sc->sc_disks_lock, SX_LOCKED); + + bioq_init(&queue); + TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { + cbp = g_clone_bio(bp); + if (cbp == NULL) { + while ((cbp = bioq_takefirst(&queue)) != NULL) + g_destroy_bio(cbp); + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + cbp->bio_done = g_ventoy_done; + cbp->bio_caller1 = disk->d_consumer; + cbp->bio_to = disk->d_consumer->provider; + } + while ((cbp = bioq_takefirst(&queue)) != NULL) { + G_VENTOY_LOGREQ(cbp, "Sending request."); + cp = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, cp); + } +} + +static void +g_ventoy_start(struct bio *bp) +{ + struct bio_queue_head queue; + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_provider *pp; + off_t offset, end, length, off, len; + struct bio *cbp; + char *addr; + + pp = bp->bio_to; + sc = pp->geom->softc; + /* + * If sc == NULL, provider's error should be set and g_ventoy_start() + * should not be called at all. + */ + KASSERT(sc != NULL, + ("Provider's error should be set (error=%d)(device=%s).", + bp->bio_to->error, bp->bio_to->name)); + + G_VENTOY_LOGREQ(bp, "Request received."); + sx_slock(&sc->sc_disks_lock); + + switch (bp->bio_cmd) { + case BIO_READ: + case BIO_WRITE: + case BIO_DELETE: + break; + case BIO_SPEEDUP: + case BIO_FLUSH: + g_ventoy_flush(sc, bp); + goto end; + case BIO_GETATTR: + if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { + g_ventoy_kernel_dump(bp); + goto end; + } else if (strcmp("GEOM::candelete", bp->bio_attribute) == 0) { + g_ventoy_candelete(bp); + goto end; + } + /* To which provider it should be delivered? */ + /* FALLTHROUGH */ + default: + g_io_deliver(bp, EOPNOTSUPP); + goto end; + } + + offset = bp->bio_offset; + length = bp->bio_length; + if ((bp->bio_flags & BIO_UNMAPPED) != 0) + addr = NULL; + else + addr = bp->bio_data; + end = offset + length; + + bioq_init(&queue); + TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { + if (disk->d_end <= offset) + continue; + if (disk->d_start >= end) + break; + + off = offset - disk->d_start; + len = MIN(length, disk->d_end - offset); + length -= len; + offset += len; + + cbp = g_clone_bio(bp); + if (cbp == NULL) { + while ((cbp = bioq_takefirst(&queue)) != NULL) + g_destroy_bio(cbp); + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + goto end; + } + bioq_insert_tail(&queue, cbp); + /* + * Fill in the component buf structure. + */ + if (len == bp->bio_length) + cbp->bio_done = g_std_done; + else + cbp->bio_done = g_ventoy_done; + cbp->bio_offset = off + disk->d_map_start; + cbp->bio_length = len; + if ((bp->bio_flags & BIO_UNMAPPED) != 0) { + cbp->bio_ma_offset += (uintptr_t)addr; + cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE; + cbp->bio_ma_offset %= PAGE_SIZE; + cbp->bio_ma_n = round_page(cbp->bio_ma_offset + + cbp->bio_length) / PAGE_SIZE; + } else + cbp->bio_data = addr; + addr += len; + cbp->bio_to = disk->d_consumer->provider; + cbp->bio_caller1 = disk; + + if (length == 0) + break; + } + KASSERT(length == 0, + ("Length is still greater than 0 (class=%s, name=%s).", + bp->bio_to->geom->class->name, bp->bio_to->geom->name)); + while ((cbp = bioq_takefirst(&queue)) != NULL) { + G_VENTOY_LOGREQ(cbp, "Sending request."); + disk = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, disk->d_consumer); + } +end: + sx_sunlock(&sc->sc_disks_lock); +} + +static void +g_ventoy_check_and_run(struct g_ventoy_softc *sc) +{ + struct g_ventoy_disk *disk; + struct g_provider *dp, *pp; + u_int sectorsize = 0; + off_t start; + int error; + + g_topology_assert(); + if (g_ventoy_nvalid(sc) != sc->sc_ndisks) + return; + + pp = g_new_providerf(sc->sc_geom, "ventoy/%s", sc->sc_name); + pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE | + G_PF_ACCEPT_UNMAPPED; + start = 0; + TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { + dp = disk->d_consumer->provider; + disk->d_start = start; + disk->d_end = disk->d_start + (disk->d_map_end - disk->d_map_start); + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) + disk->d_end -= dp->sectorsize; + start = disk->d_end; + error = g_access(disk->d_consumer, 1, 0, 0); + if (error == 0) { + error = g_getattr("GEOM::candelete", disk->d_consumer, + &disk->d_candelete); + if (error != 0) + disk->d_candelete = 0; + (void)g_access(disk->d_consumer, -1, 0, 0); + } else + G_VENTOY_DEBUG(1, "Failed to access disk %s, error %d.", + dp->name, error); + if (disk == TAILQ_FIRST(&sc->sc_disks)) + sectorsize = dp->sectorsize; + else + sectorsize = lcm(sectorsize, dp->sectorsize); + + /* A provider underneath us doesn't support unmapped */ + if ((dp->flags & G_PF_ACCEPT_UNMAPPED) == 0) { + G_VENTOY_DEBUG(1, "Cancelling unmapped " + "because of %s.", dp->name); + pp->flags &= ~G_PF_ACCEPT_UNMAPPED; + } + } + pp->sectorsize = sectorsize; + /* We have sc->sc_disks[sc->sc_ndisks - 1].d_end in 'start'. */ + pp->mediasize = start; + dp = TAILQ_FIRST(&sc->sc_disks)->d_consumer->provider; + pp->stripesize = dp->stripesize; + pp->stripeoffset = dp->stripeoffset; + sc->sc_provider = pp; + g_error_provider(pp, 0); + + G_VENTOY_DEBUG(0, "Device %s activated.", sc->sc_provider->name); +} + +static int +g_ventoy_read_metadata(struct g_consumer *cp, struct g_ventoy_metadata *md) +{ + struct g_provider *pp; + u_char *buf; + int error; + + g_topology_assert(); + + error = g_access(cp, 1, 0, 0); + if (error != 0) + return (error); + pp = cp->provider; + g_topology_unlock(); + buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, + &error); + g_topology_lock(); + g_access(cp, -1, 0, 0); + if (buf == NULL) + return (error); + + /* Decode metadata. */ + ventoy_metadata_decode(buf, md); + g_free(buf); + + return (0); +} + +/* + * Add disk to given device. + */ +static int +g_ventoy_add_disk(struct g_ventoy_softc *sc, struct g_provider *pp, u_int no) +{ + struct g_ventoy_disk *disk; + struct g_consumer *cp, *fcp; + struct g_geom *gp; + int error; + + g_topology_assert(); + + sx_slock(&sc->sc_disks_lock); + + /* Metadata corrupted? */ + if (no >= sc->sc_ndisks) { + sx_sunlock(&sc->sc_disks_lock); + return (EINVAL); + } + + for (disk = TAILQ_FIRST(&sc->sc_disks); no > 0; no--) { + disk = TAILQ_NEXT(disk, d_next); + } + + /* Check if disk is not already attached. */ + if (disk->d_consumer != NULL) { + sx_sunlock(&sc->sc_disks_lock); + return (EEXIST); + } + + gp = sc->sc_geom; + fcp = LIST_FIRST(&gp->consumer); + + cp = g_new_consumer(gp); + cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; + error = g_attach(cp, pp); + if (error != 0) { + sx_sunlock(&sc->sc_disks_lock); + g_destroy_consumer(cp); + return (error); + } + + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) { + error = g_access(cp, fcp->acr, fcp->acw, fcp->ace); + if (error != 0) { + sx_sunlock(&sc->sc_disks_lock); + g_detach(cp); + g_destroy_consumer(cp); + return (error); + } + } + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) { + struct g_ventoy_metadata md; + + // temporarily give up the lock to avoid lock order violation + // due to topology unlock in g_concat_read_metadata + sx_sunlock(&sc->sc_disks_lock); + /* Re-read metadata. */ + error = g_ventoy_read_metadata(cp, &md); + sx_slock(&sc->sc_disks_lock); + + if (error != 0) + goto fail; + + if (strcmp(md.md_magic, G_VENTOY_MAGIC) != 0 || + strcmp(md.md_name, sc->sc_name) != 0 || + md.md_id != sc->sc_id) { + G_VENTOY_DEBUG(0, "Metadata on %s changed.", pp->name); + goto fail; + } + + disk->d_hardcoded = md.md_provider[0] != '\0'; + } else { + disk->d_hardcoded = false; + } + + cp->private = disk; + disk->d_consumer = cp; + disk->d_softc = sc; + disk->d_start = 0; /* not yet */ + disk->d_end = 0; /* not yet */ + disk->d_removed = 0; + + disk->d_map_start = g_disk_map_start; + disk->d_map_end = g_disk_map_end; + + G_VENTOY_DEBUG(0, "Disk %s attached to %s.", pp->name, sc->sc_name); + + g_ventoy_check_and_run(sc); + sx_sunlock(&sc->sc_disks_lock); // need lock for check_and_run + + return (0); +fail: + sx_sunlock(&sc->sc_disks_lock); // need lock for check_and_run + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) + g_access(cp, -fcp->acr, -fcp->acw, -fcp->ace); + g_detach(cp); + g_destroy_consumer(cp); + return (error); +} + +static struct g_geom * +g_ventoy_create(struct g_class *mp, const struct g_ventoy_metadata *md, + u_int type) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_geom *gp; + u_int no; + + G_VENTOY_DEBUG(1, "Creating device %s (id=%u).", md->md_name, + md->md_id); + + /* One disks is minimum. */ + if (md->md_all < 1) + return (NULL); + + /* Check for duplicate unit */ + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc != NULL && strcmp(sc->sc_name, md->md_name) == 0) { + G_VENTOY_DEBUG(0, "Device %s already configured.", + gp->name); + return (NULL); + } + } + gp = g_new_geomf(mp, "%s", md->md_name); + sc = malloc(sizeof(*sc), M_VENTOY, M_WAITOK | M_ZERO); + gp->start = g_ventoy_start; + gp->spoiled = g_ventoy_orphan; + gp->orphan = g_ventoy_orphan; + gp->access = g_ventoy_access; + gp->dumpconf = g_ventoy_dumpconf; + + sc->sc_id = md->md_id; + sc->sc_ndisks = md->md_all; + TAILQ_INIT(&sc->sc_disks); + for (no = 0; no < sc->sc_ndisks; no++) { + disk = malloc(sizeof(*disk), M_VENTOY, M_WAITOK | M_ZERO); + TAILQ_INSERT_TAIL(&sc->sc_disks, disk, d_next); + } + sc->sc_type = type; + mtx_init(&sc->sc_completion_lock, "gventoy lock", NULL, MTX_DEF); + sx_init(&sc->sc_disks_lock, "gventoy append lock"); + + gp->softc = sc; + sc->sc_geom = gp; + sc->sc_provider = NULL; + + G_VENTOY_DEBUG(0, "Device %s created (id=%u).", sc->sc_name, sc->sc_id); + + return (gp); +} + +static int +g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force) +{ + struct g_provider *pp; + struct g_consumer *cp, *cp1; + struct g_geom *gp; + struct g_ventoy_disk *disk; + + g_topology_assert(); + + if (sc == NULL) + return (ENXIO); + + pp = sc->sc_provider; + if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) { + if (force) { + G_VENTOY_DEBUG(0, "Device %s is still open, so it " + "can't be definitely removed.", pp->name); + } else { + G_VENTOY_DEBUG(1, + "Device %s is still open (r%dw%de%d).", pp->name, + pp->acr, pp->acw, pp->ace); + return (EBUSY); + } + } + + gp = sc->sc_geom; + LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp1) { + g_ventoy_remove_disk(cp->private); + if (cp1 == NULL) + return (0); /* Recursion happened. */ + } + if (!LIST_EMPTY(&gp->consumer)) + return (EINPROGRESS); + + gp->softc = NULL; + KASSERT(sc->sc_provider == NULL, ("Provider still exists? (device=%s)", + gp->name)); + while ((disk = TAILQ_FIRST(&sc->sc_disks)) != NULL) { + TAILQ_REMOVE(&sc->sc_disks, disk, d_next); + free(disk, M_VENTOY); + } + mtx_destroy(&sc->sc_completion_lock); + sx_destroy(&sc->sc_disks_lock); + free(sc, M_VENTOY); + + G_VENTOY_DEBUG(0, "Device %s destroyed.", gp->name); + g_wither_geom(gp, ENXIO); + return (0); +} + +static int +g_ventoy_destroy_geom(struct gctl_req *req __unused, + struct g_class *mp __unused, struct g_geom *gp) +{ + struct g_ventoy_softc *sc; + + sc = gp->softc; + return (g_ventoy_destroy(sc, 0)); +} + +static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) +{ + int i; + int vlnk = 0; + bool ret = true; + uint8_t *buf; + char uuid[64]; + const char *value; + struct g_consumer *cp; + struct g_geom *gp; + uint8_t mbrdata[] = { + 0xEB, 0x63, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44, 0x00, 0x52, 0x64, 0x00, 0x20, 0x45, 0x72, 0x0D, + }; + + if (g_ventoy_disk_size == 0) + { + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) + { + G_DEBUG("ventoy map data is valid. [OK]\n"); + + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", g_ventoy_map_data.diskuuid[i]); + } + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", uuid); + g_ventoy_disk_size = g_ventoy_map_data.disksize; + + G_DEBUG("ventoy.disksize: %llu\n", (unsigned long long)g_ventoy_disk_size); + G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid); + } + else + { + G_DEBUG("ventoy map data is invalid, get from resource\n"); + + if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + { + G_DEBUG("ventoy.disksize: %s\n", value); + g_ventoy_disk_size = strtouq(value, NULL, 0); + } + + if (resource_string_value("ventoy", 0, "diskuuid", &value) == 0) + { + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", value); + G_DEBUG("ventoy.diskuuid: <%s>\n", value); + } + } + } + + if (g_ventoy_disk_size != pp->mediasize) + { + return false; + } + + if (strncmp(pp->name, "cd", 2) == 0 || strchr(pp->name, '/')) + { + return false; + } + + /* read UUID from disk */ + gp = g_new_geomf(mp, "ventoy:taste"); + gp->start = NULL; + gp->access = g_ventoy_access; + gp->orphan = g_ventoy_orphan; + cp = g_new_consumer(gp); + cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; + g_attach(cp, pp); + + g_access(cp, 1, 0, 0); + g_topology_unlock(); + buf = g_read_data(cp, 0, pp->sectorsize, NULL); + g_topology_lock(); + g_access(cp, -1, 0, 0); + + g_detach(cp); + g_destroy_consumer(cp); + g_destroy_geom(gp); + gp = NULL; + + if (!buf) + { + return false; + } + + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", buf[0x180 + i]); + } + + if (strncmp(g_ventoy_disk_uuid, uuid, 32)) + { + ret = false; + } + + if (resource_int_value("ventoy", 0, "vlnk", &vlnk) || (vlnk != 1)) + { + if (memcmp(mbrdata, buf, 0x30) || memcmp(mbrdata + 0x30, buf + 0x190, 16)) + { + ret = false; + } + } + + g_free(buf); + + if (ret) + { + G_DEBUG("ventoy disk check OK\n"); + } + + return ret; +} + +static struct g_geom * +g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) +{ + int i; + int error; + int disknum; + int remount = 0; + char *endpos; + const char *value; + const char *alias = NULL; + struct g_geom *gp; + struct g_ventoy_metadata md; + struct g_ventoy_softc *sc; + + if (g_ventoy_tasted) + { + return NULL; + } + + G_DEBUG("%s(%s, %s)\n", __func__, mp->name, pp->name); + g_topology_assert(); + + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + + if (!g_vtoy_check_disk(mp, pp)) + { + return NULL; + } + + g_ventoy_tasted = true; + + G_DEBUG("###### ventoy disk <%s> ######\n", pp->name); + + /* hint.ventoy.0.remount=1 */ + if (resource_int_value("ventoy", 0, "remount", &remount) == 0 && remount == 1) + { + g_ventoy_remount = 1; + G_DEBUG("###### ventoy remount enabled ######\n"); + } + + /* hint.ventoy.0.alias=xxx */ + if (resource_string_value("ventoy", 0, "alias", &alias) == 0) + { + G_DEBUG("###### ventoy alias <%s> ######\n", alias); + } + else + { + alias = NULL; + } + + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) + { + disknum = (int)g_ventoy_map_data.segnum; + G_DEBUG("segnum from map data is:<%d>\n", disknum); + } + else + { + resource_int_value("ventoy", 0, "segnum", &disknum); + G_DEBUG("segnum from resource is:<%d>\n", disknum); + } + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + strlcpy(md.md_name, "IMAGE", sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = (uint16_t)disknum; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + G_VENTOY_DEBUG(0, "Cannot create device %s.", + md.md_name); + return (NULL); + } + sc = gp->softc; + + for (i = 0; i < disknum; i ++) + { + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) + { + G_DEBUG("[map] ventoy segment%d: 0x%llx@0x%llx\n", i, + (long long)g_ventoy_map_data.seglist[i].seg_start_bytes, + (long long)g_ventoy_map_data.seglist[i].seg_end_bytes); + + g_disk_map_start = (off_t)g_ventoy_map_data.seglist[i].seg_start_bytes; + g_disk_map_end = (off_t)g_ventoy_map_data.seglist[i].seg_end_bytes; + } + else + { + if (resource_string_value("ventoy", i, "seg", &value) == 0) + { + g_disk_map_start = strtouq(value, &endpos, 0); + g_disk_map_end = strtouq(endpos + 1, NULL, 0); + } + else + { + printf("Failed to parse ventoy seg %d\n", i); + continue; + } + G_DEBUG("[resource] ventoy segment%d: %s\n", i, value); + } + + G_VENTOY_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name); + error = g_ventoy_add_disk(sc, pp, i); + if (error != 0) { + G_VENTOY_DEBUG(0, + "Cannot add disk %s to %s (error=%d).", pp->name, + gp->name, error); + g_ventoy_destroy(sc, 1); + return (NULL); + } + + g_disk_map_start = 0; + g_disk_map_end = 0; + } + + if (alias && sc && sc->sc_provider) + { + g_provider_add_alias(sc->sc_provider, "%s", alias); + } + + return (gp); +} + +static void +g_ventoy_ctl_create(struct gctl_req *req, struct g_class *mp) +{ + u_int attached, no; + struct g_ventoy_metadata md; + struct g_provider *pp; + struct g_ventoy_softc *sc; + struct g_geom *gp; + struct sbuf *sb; + const char *name; + char param[16]; + int *nargs; + + g_topology_assert(); + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs < 2) { + gctl_error(req, "Too few arguments."); + return; + } + + bzero(&md, sizeof(md)); + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + name = gctl_get_asciiparam(req, "arg0"); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", 0); + return; + } + strlcpy(md.md_name, name, sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = *nargs - 1; + /* This field is not important here. */ + md.md_provsize = 0; + + /* Check all providers are valid */ + for (no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + pp = gctl_get_provider(req, param); + if (pp == NULL) + return; + } + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + gctl_error(req, "Can't configure %s.", md.md_name); + return; + } + + sc = gp->softc; + sb = sbuf_new_auto(); + sbuf_printf(sb, "Can't attach disk(s) to %s:", gp->name); + for (attached = 0, no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + pp = gctl_get_provider(req, param); + if (pp == NULL) { + name = gctl_get_asciiparam(req, param); + MPASS(name != NULL); + sbuf_printf(sb, " %s", name); + continue; + } + if (g_ventoy_add_disk(sc, pp, no - 1) != 0) { + G_VENTOY_DEBUG(1, "Disk %u (%s) not attached to %s.", + no, pp->name, gp->name); + sbuf_printf(sb, " %s", pp->name); + continue; + } + attached++; + } + sbuf_finish(sb); + if (md.md_all != attached) { + g_ventoy_destroy(gp->softc, 1); + gctl_error(req, "%s", sbuf_data(sb)); + } + sbuf_delete(sb); +} + +static struct g_ventoy_softc * +g_ventoy_find_device(struct g_class *mp, const char *name) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + + if (strncmp(name, _PATH_DEV, strlen(_PATH_DEV)) == 0) + name += strlen(_PATH_DEV); + + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc == NULL) + continue; + if (strcmp(sc->sc_name, name) == 0) + return (sc); + } + return (NULL); +} + +static void +g_ventoy_ctl_destroy(struct gctl_req *req, struct g_class *mp) +{ + struct g_ventoy_softc *sc; + int *force, *nargs, error; + const char *name; + char param[16]; + u_int i; + + g_topology_assert(); + + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs <= 0) { + gctl_error(req, "Missing device(s)."); + return; + } + force = gctl_get_paraml(req, "force", sizeof(*force)); + if (force == NULL) { + gctl_error(req, "No '%s' argument.", "force"); + return; + } + + for (i = 0; i < (u_int)*nargs; i++) { + snprintf(param, sizeof(param), "arg%u", i); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", i); + return; + } + sc = g_ventoy_find_device(mp, name); + if (sc == NULL) { + gctl_error(req, "No such device: %s.", name); + return; + } + error = g_ventoy_destroy(sc, *force); + if (error != 0) { + gctl_error(req, "Cannot destroy device %s (error=%d).", + sc->sc_name, error); + return; + } + } +} + +static void +g_ventoy_config(struct gctl_req *req, struct g_class *mp, const char *verb) +{ + uint32_t *version; + + return; + + g_topology_assert(); + + version = gctl_get_paraml(req, "version", sizeof(*version)); + if (version == NULL) { + gctl_error(req, "No '%s' argument.", "version"); + return; + } + if (*version != G_VENTOY_VERSION) { + gctl_error(req, "Userland and kernel parts are out of sync."); + return; + } + + if (strcmp(verb, "create") == 0) { + g_ventoy_ctl_create(req, mp); + return; + } else if (strcmp(verb, "destroy") == 0 || + strcmp(verb, "stop") == 0) { + g_ventoy_ctl_destroy(req, mp); + return; + } + gctl_error(req, "Unknown verb."); +} + +static void +g_ventoy_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, + struct g_consumer *cp, struct g_provider *pp) +{ + struct g_ventoy_softc *sc; + + g_topology_assert(); + sc = gp->softc; + if (sc == NULL) + return; + sx_slock(&sc->sc_disks_lock); + if (pp != NULL) { + /* Nothing here. */ + } else if (cp != NULL) { + struct g_ventoy_disk *disk; + + disk = cp->private; + if (disk == NULL) + goto end; + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_end); + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_start); + } else { + sbuf_printf(sb, "%s%u\n", indent, (u_int)sc->sc_id); + sbuf_printf(sb, "%s", indent); + switch (sc->sc_type) { + case G_VENTOY_TYPE_AUTOMATIC: + sbuf_cat(sb, "AUTOMATIC"); + break; + case G_VENTOY_TYPE_MANUAL: + sbuf_cat(sb, "MANUAL"); + break; + default: + sbuf_cat(sb, "UNKNOWN"); + break; + } + sbuf_cat(sb, "\n"); + sbuf_printf(sb, "%sTotal=%u, Online=%u\n", + indent, sc->sc_ndisks, g_ventoy_nvalid(sc)); + sbuf_printf(sb, "%s", indent); + if (sc->sc_provider != NULL && sc->sc_provider->error == 0) + sbuf_cat(sb, "UP"); + else + sbuf_cat(sb, "DOWN"); + sbuf_cat(sb, "\n"); + } +end: + sx_sunlock(&sc->sc_disks_lock); +} + +DECLARE_GEOM_CLASS(g_ventoy_class, g_ventoy); +//MODULE_VERSION(geom_ventoy, 0); diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.h b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.h new file mode 100644 index 00000000..ad5961ae --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/geom/ventoy/g_ventoy.h @@ -0,0 +1,147 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _G_VENTOY_H_ +#define _G_VENTOY_H_ + +#include + +#define G_VENTOY_CLASS_NAME "VENTOY" + +#define G_VENTOY_MAGIC "GEOM::VENTOY" +/* + * Version history: + * 1 - Initial version number. + * 2 - Added 'stop' command to gconcat(8). + * 3 - Added md_provider field to metadata and '-h' option to gconcat(8). + * 4 - Added md_provsize field to metadata. + */ +#define G_VENTOY_VERSION 4 + +#ifdef _KERNEL +#define G_VENTOY_TYPE_MANUAL 0 +#define G_VENTOY_TYPE_AUTOMATIC 1 + +#define G_DEBUG(...) if (bootverbose) printf(__VA_ARGS__) +#define G_VENTOY_DEBUG(lvl, ...) if (g_ventoy_debug) printf(__VA_ARGS__) +#define G_VENTOY_LOGREQ(bp, ...) if (g_ventoy_debug) printf(__VA_ARGS__) + +struct g_ventoy_disk { + TAILQ_ENTRY(g_ventoy_disk) d_next; + struct g_consumer *d_consumer; + struct g_ventoy_softc *d_softc; + off_t d_start; + off_t d_end; + off_t d_map_start; + off_t d_map_end; + int d_candelete; + int d_removed; + bool d_hardcoded; +}; + +struct g_ventoy_softc { + u_int sc_type; /* provider type */ + struct g_geom *sc_geom; + struct g_provider *sc_provider; + uint32_t sc_id; /* concat unique ID */ + + uint16_t sc_ndisks; + TAILQ_HEAD(g_ventoy_disks, g_ventoy_disk) sc_disks; + struct mtx sc_completion_lock; /* synchronizes cross-boundary IOs */ + struct sx sc_disks_lock; /* synchronizes modification of sc_disks */ +}; +#define sc_name sc_geom->name + + +#pragma pack(1) +#define VENTOY_UNIX_SEG_MAGIC0 0x11223344 +#define VENTOY_UNIX_SEG_MAGIC1 0x55667788 +#define VENTOY_UNIX_SEG_MAGIC2 0x99aabbcc +#define VENTOY_UNIX_SEG_MAGIC3 0xddeeff00 +#define VENTOY_UNIX_MAX_SEGNUM 40960 +struct g_ventoy_seg { + uint64_t seg_start_bytes; + uint64_t seg_end_bytes; +}; + +struct g_ventoy_map{ + uint32_t magic1[4]; + uint32_t magic2[4]; + uint64_t segnum; + uint64_t disksize; + uint8_t diskuuid[16]; + struct g_ventoy_seg seglist[VENTOY_UNIX_MAX_SEGNUM]; + uint32_t magic3[4]; +}; +#pragma pack() + +#define VENTOY_MAP_VALID(magic2) \ + (magic2[0] == VENTOY_UNIX_SEG_MAGIC0 && magic2[1] == VENTOY_UNIX_SEG_MAGIC1 && magic2[2] == VENTOY_UNIX_SEG_MAGIC2 && magic2[3] == VENTOY_UNIX_SEG_MAGIC3) + +#endif /* _KERNEL */ + +struct g_ventoy_metadata { + char md_magic[16]; /* Magic value. */ + uint32_t md_version; /* Version number. */ + char md_name[16]; /* Concat name. */ + uint32_t md_id; /* Unique ID. */ + uint16_t md_no; /* Disk number. */ + uint16_t md_all; /* Number of all disks. */ + char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ +}; +static __inline void +ventoy_metadata_encode(const struct g_ventoy_metadata *md, u_char *data) +{ + + bcopy(md->md_magic, data, sizeof(md->md_magic)); + le32enc(data + 16, md->md_version); + bcopy(md->md_name, data + 20, sizeof(md->md_name)); + le32enc(data + 36, md->md_id); + le16enc(data + 40, md->md_no); + le16enc(data + 42, md->md_all); + bcopy(md->md_provider, data + 44, sizeof(md->md_provider)); + le64enc(data + 60, md->md_provsize); +} +static __inline void +ventoy_metadata_decode(const u_char *data, struct g_ventoy_metadata *md) +{ + + bcopy(data, md->md_magic, sizeof(md->md_magic)); + md->md_version = le32dec(data + 16); + bcopy(data + 20, md->md_name, sizeof(md->md_name)); + md->md_id = le32dec(data + 36); + md->md_no = le16dec(data + 40); + md->md_all = le16dec(data + 42); + bcopy(data + 44, md->md_provider, sizeof(md->md_provider)); + md->md_provsize = le64dec(data + 60); +} +#endif /* _G_VENTOY_H_ */ diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/modules/geom/geom_ventoy/Makefile b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/modules/geom/geom_ventoy/Makefile new file mode 100644 index 00000000..165f1bdf --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/14.x/sys/modules/geom/geom_ventoy/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/geom/ventoy + +KMOD= geom_ventoy +SRCS= g_ventoy.c + +.include