git: 4ef1c6f75d25 - main - base: Remove support for the VTOC8 partitioning scheme
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 26 Jul 2023 11:29:01 UTC
The branch main has been updated by marius: URL: https://cgit.FreeBSD.org/src/commit/?id=4ef1c6f75d25ba0c264ab274a1b449467a6ee817 commit 4ef1c6f75d25ba0c264ab274a1b449467a6ee817 Author: Marius Strobl <marius@FreeBSD.org> AuthorDate: 2023-07-26 11:08:37 +0000 Commit: Marius Strobl <marius@FreeBSD.org> CommitDate: 2023-07-26 11:16:12 +0000 base: Remove support for the VTOC8 partitioning scheme The removal of the sparc64 support in February 2020 obsoleted the VTOC8 partitioning scheme as no other FreeBSD platform makes use of it. Moreover, the code is bitrotting as nothing defines e. g. LOADER_VTOC8_SUPPORT any more and, thus, should go now, too. With this change, the following commits are reverted as far as VTOC8 is concerned and parts haven't already previously been deleted along with prior sparc64 removals: 094fcb157d4c98211899cf09d06e2cf19149b7e0 a7d366e9589c95feda6f3bc78c59c6355d51f126 ba8d50d08b9df4e8213f9a6997ff6792ecebcd9b The alignment example d9711c28efc4ec89ba5ea11f8fd63e9d0a7fc81b added to the VTOC8 section of gpart.8 is folded into the MBR one. This should finally conclude the deorbit of sparc64-specific bits. We had joy, we had fun we ran Unix on a Sun. But that source and the song of FreeBSD have all gone. Credits to Michael Bueker for the original "Unix on a Sun" and Rod McKuen for the "Seasons in the Sun" lyrics. --- ObsoleteFiles.inc | 4 + lib/geom/part/geom_part.c | 132 ++--- lib/geom/part/gpart.8 | 76 +-- share/man/man4/geom.4 | 5 +- stand/common/part.c | 100 ---- stand/common/part.h | 1 - sys/conf/NOTES | 1 - sys/conf/files | 1 - sys/conf/options | 1 - sys/geom/part/g_part_vtoc8.c | 604 --------------------- sys/modules/geom/geom_part/Makefile | 3 +- .../geom/geom_part/geom_part_vtoc8/Makefile | 10 - sys/sys/disk/vtoc.h | 110 ---- sys/sys/vtoc.h | 5 - tools/boot/install-boot.sh | 12 - usr.bin/mkimg/Makefile | 3 +- usr.bin/mkimg/tests/mkimg_test.sh | 2 +- usr.bin/mkimg/vtoc8.c | 113 ---- usr.sbin/efibootmgr/efibootmgr.c | 1 - 19 files changed, 58 insertions(+), 1126 deletions(-) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 0dc315ee64ba..3acb677c25e4 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -52,6 +52,10 @@ # xargs -n1 | sort | uniq -d; # done +# 20230726: Removal of support for the VTOC8 partitioning scheme +OLD_FILES+=usr/include/sys/disk/vtoc.h +OLD_FILES+=usr/include/sys/vtoc.h + # 20230724: Remove unneeded arm headers .if ${TARGET_ARCH} == "arm" OLD_FILES+=usr/include/machine/atomic-v6.h diff --git a/lib/geom/part/geom_part.c b/lib/geom/part/geom_part.c index 70eb83a66c97..04e730c7719e 100644 --- a/lib/geom/part/geom_part.c +++ b/lib/geom/part/geom_part.c @@ -30,7 +30,6 @@ __FBSDID("$FreeBSD$"); #include <sys/stat.h> -#include <sys/vtoc.h> #include <assert.h> #include <ctype.h> @@ -89,8 +88,7 @@ static _Noreturn void gpart_issue(struct gctl_req *, unsigned int); static void gpart_show(struct gctl_req *, unsigned int); static void gpart_show_geom(struct ggeom *, const char *, int); static int gpart_show_hasopt(struct gctl_req *, const char *, const char *); -static void gpart_write_partcode(struct ggeom *, int, void *, ssize_t); -static void gpart_write_partcode_vtoc8(struct ggeom *, int, void *); +static void gpart_write_partcode(struct gctl_req *, int, void *, ssize_t); static void gpart_print_error(const char *); static void gpart_backup(struct gctl_req *, unsigned int); static void gpart_restore(struct gctl_req *, unsigned int); @@ -1107,14 +1105,38 @@ gpart_bootfile_read(const char *bootfile, ssize_t *size) } static void -gpart_write_partcode(struct ggeom *gp, int idx, void *code, ssize_t size) +gpart_write_partcode(struct gctl_req *req, int idx, void *code, ssize_t size) { char dsf[128]; + struct gmesh mesh; + struct gclass *classp; + struct ggeom *gp; struct gprovider *pp; - const char *s; + const char *g, *s; char *buf; off_t bsize; - int fd; + int error, fd; + + s = gctl_get_ascii(req, "class"); + if (s == NULL) + abort(); + g = gctl_get_ascii(req, "arg0"); + if (g == NULL) + abort(); + error = geom_gettree_geom(&mesh, s, g, 0); + if (error != 0) + errc(EXIT_FAILURE, error, "Cannot get GEOM tree"); + classp = find_class(&mesh, s); + if (classp == NULL) { + geom_deletetree(&mesh); + errx(EXIT_FAILURE, "Class %s not found.", s); + } + gp = find_geom(classp, g); + if (gp == NULL) + errx(EXIT_FAILURE, "No such geom: %s.", g); + s = find_geomcfg(gp, "scheme"); + if (s == NULL) + errx(EXIT_FAILURE, "Scheme not found for geom %s", gp->lg_name); LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { s = find_provcfg(pp, "index"); @@ -1149,65 +1171,17 @@ gpart_write_partcode(struct ggeom *gp, int idx, void *code, ssize_t size) printf("partcode written to %s\n", pp->lg_name); } else errx(EXIT_FAILURE, "invalid partition index"); -} -static void -gpart_write_partcode_vtoc8(struct ggeom *gp, int idx, void *code) -{ - char dsf[128]; - struct gprovider *pp; - const char *s; - int installed, fd; - - installed = 0; - LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { - s = find_provcfg(pp, "index"); - if (s == NULL) - continue; - if (idx != 0 && atoi(s) != idx) - continue; - snprintf(dsf, sizeof(dsf), "/dev/%s", pp->lg_name); - if (pp->lg_sectorsize != sizeof(struct vtoc8)) - errx(EXIT_FAILURE, "%s: unexpected sector " - "size (%d)\n", dsf, pp->lg_sectorsize); - if (pp->lg_mediasize < VTOC_BOOTSIZE) - continue; - fd = open(dsf, O_WRONLY); - if (fd == -1) - err(EXIT_FAILURE, "%s", dsf); - /* - * We ignore the first VTOC_BOOTSIZE bytes of boot code in - * order to avoid overwriting the label. - */ - if (lseek(fd, sizeof(struct vtoc8), SEEK_SET) != - sizeof(struct vtoc8)) - err(EXIT_FAILURE, "%s", dsf); - if (write(fd, (caddr_t)code + sizeof(struct vtoc8), - VTOC_BOOTSIZE - sizeof(struct vtoc8)) != VTOC_BOOTSIZE - - sizeof(struct vtoc8)) - err(EXIT_FAILURE, "%s", dsf); - installed++; - close(fd); - if (idx != 0 && atoi(s) == idx) - break; - } - if (installed == 0) - errx(EXIT_FAILURE, "%s: no partitions", gp->lg_name); - else - printf("partcode written to %s\n", - idx != 0 ? pp->lg_name: gp->lg_name); + geom_deletetree(&mesh); } static void gpart_bootcode(struct gctl_req *req, unsigned int fl) { - struct gmesh mesh; - struct gclass *classp; - struct ggeom *gp; - const char *g, *s; + const char *s; void *bootcode, *partcode; size_t bootsize, partsize; - int error, idx, vtoc8; + int error, idx; if (gctl_get_int(req, "nargs") != 1) errx(EXIT_FAILURE, "Invalid number of arguments."); @@ -1231,31 +1205,6 @@ gpart_bootcode(struct gctl_req *req, unsigned int fl) goto nopartcode; } - s = gctl_get_ascii(req, "class"); - if (s == NULL) - abort(); - g = gctl_get_ascii(req, "arg0"); - if (g == NULL) - abort(); - error = geom_gettree_geom(&mesh, s, g, 0); - if (error != 0) - errc(EXIT_FAILURE, error, "Cannot get GEOM tree"); - classp = find_class(&mesh, s); - if (classp == NULL) { - geom_deletetree(&mesh); - errx(EXIT_FAILURE, "Class %s not found.", s); - } - gp = find_geom(classp, g); - if (gp == NULL) - errx(EXIT_FAILURE, "No such geom: %s.", g); - s = find_geomcfg(gp, "scheme"); - if (s == NULL) - errx(EXIT_FAILURE, "Scheme not found for geom %s", gp->lg_name); - if (strcmp(s, "VTOC8") == 0) - vtoc8 = 1; - else - vtoc8 = 0; - if (gctl_has_param(req, GPART_PARAM_INDEX)) { idx = (int)gctl_get_intmax(req, GPART_PARAM_INDEX); if (idx < 1) @@ -1268,28 +1217,17 @@ gpart_bootcode(struct gctl_req *req, unsigned int fl) if (gctl_has_param(req, GPART_PARAM_PARTCODE)) { s = gctl_get_ascii(req, GPART_PARAM_PARTCODE); - if (vtoc8 != 0) - partsize = VTOC_BOOTSIZE; - else - partsize = 1024 * 1024; /* Arbitrary limit. */ + partsize = 1024 * 1024; /* Arbitrary limit. */ partcode = gpart_bootfile_read(s, &partsize); error = gctl_delete_param(req, GPART_PARAM_PARTCODE); if (error) errc(EXIT_FAILURE, error, "internal error"); - if (vtoc8 == 0) { - if (idx == 0) - errx(EXIT_FAILURE, "missing -i option"); - gpart_write_partcode(gp, idx, partcode, partsize); - } else { - if (partsize != VTOC_BOOTSIZE) - errx(EXIT_FAILURE, "invalid bootcode"); - gpart_write_partcode_vtoc8(gp, idx, partcode); - } + if (idx == 0) + errx(EXIT_FAILURE, "missing -i option"); + gpart_write_partcode(req, idx, partcode, partsize); free(partcode); } - geom_deletetree(&mesh); - nopartcode: if (bootcode != NULL) gpart_issue(req, fl); diff --git a/lib/geom/part/gpart.8 b/lib/geom/part/gpart.8 index 2bc1daba2ad6..a6f9fbd884a8 100644 --- a/lib/geom/part/gpart.8 +++ b/lib/geom/part/gpart.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 7, 2023 +.Dd July 26, 2023 .Dt GPART 8 .Os .Sh NAME @@ -544,7 +544,7 @@ See Several partitioning schemes are supported by the .Nm utility: -.Bl -tag -width ".Cm VTOC8" +.Bl -tag -width ".Cm BSD64" .It Cm APM Apple Partition Map, used by PowerPC(R) Macintosh(R) computers. Requires the @@ -599,15 +599,6 @@ The option enables backward compatibility for partition names in the EBR scheme. It also prevents any type of actions on such partitions. -.It Cm VTOC8 -Sun's SMI Volume Table Of Contents, used by -.Tn SPARC64 -and -.Tn UltraSPARC -computers. -Requires the -.Cm GEOM_PART_VTOC8 -kernel option. .El .Pp See @@ -680,36 +671,36 @@ A partition dedicated to swap space. The scheme-specific types are .Qq Li "!FreeBSD-swap" -for APM, +for APM, and .Qq Li "!516e7cb5-6ecf-11d6-8ff8-00022d09712b" -for GPT, and tag 0x0901 for VTOC8. +for GPT. .It Cm freebsd-ufs A .Fx partition that contains a UFS or UFS2 filesystem. The scheme-specific types are .Qq Li "!FreeBSD-UFS" -for APM, +for APM, and .Qq Li "!516e7cb6-6ecf-11d6-8ff8-00022d09712b" -for GPT, and tag 0x0902 for VTOC8. +for GPT. .It Cm freebsd-vinum A .Fx partition that contains a Vinum volume. The scheme-specific types are .Qq Li "!FreeBSD-Vinum" -for APM, +for APM, and .Qq Li "!516e7cb8-6ecf-11d6-8ff8-00022d09712b" -for GPT, and tag 0x0903 for VTOC8. +for GPT. .It Cm freebsd-zfs A .Fx partition that contains a ZFS volume. The scheme-specific types are .Qq Li "!FreeBSD-ZFS" -for APM, +for APM, and .Qq Li "!516e7cba-6ecf-11d6-8ff8-00022d09712b" -for GPT, and 0x0904 for VTOC8. +for GPT. .El .Pp Other symbolic names that can be used with the @@ -1196,18 +1187,6 @@ After all pools are detected, .Pa /boot/loader is started from the first one found set as bootable. .Pp -The VTOC8 scheme does not support embedding bootstrap code. -Instead, the 8 KBytes bootstrap code image -.Pa /boot/boot1 -should be written with the -.Cm gpart bootcode -command with the -.Fl p Ar bootcode -option to all sufficiently large VTOC8 partitions. -To do this the -.Fl i Ar index -option could be omitted. -.Pp The APM scheme also does not support embedding bootstrap code. Instead, the 800 KBytes bootstrap code image .Pa /boot/boot1.hfs @@ -1306,7 +1285,7 @@ GEOM class. The default value is shown next to each variable. .Bl -tag -width indent .It Va kern.geom.part.allow_nesting : No 0 -By default, some schemes (currently BSD, BSD64 and VTOC8) do not permit +By default, some schemes (currently BSD and BSD64) do not permit further nested partitioning. This variable overrides this restriction and allows arbitrary nesting (except within partitions created at offset 0). @@ -1443,12 +1422,12 @@ using a traditional .Bx disklabel. .Pp -First, we create the partition table and a single 64 GB partition, -then we mark that partition active (bootable) and install the -first-stage boot loader: +First, we create the partition table as well as a single partition 64 GB in +size and an alignment of 4 kB, then we mark that partition active (bootable) +and install the first-stage boot loader: .Bd -literal -offset indent /sbin/gpart create -s MBR ada0 -/sbin/gpart add -t freebsd -s 64G ada0 +/sbin/gpart add -t freebsd -s 64G -a 4k ada0 /sbin/gpart set -a active -i 1 ada0 /sbin/gpart bootcode -b /boot/boot0 ada0 .Ed @@ -1475,31 +1454,6 @@ label: .Bd -literal -offset indent /sbin/gpart bootcode -b /boot/boot ada0s1 .Ed -.Ss VTOC8 -Create a VTOC8 scheme on -.Pa da0 : -.Bd -literal -offset indent -/sbin/gpart create -s VTOC8 da0 -.Ed -.Pp -Create a 512MB-sized -.Cm freebsd-ufs -partition to contain a UFS filesystem from which the system can boot. -.Bd -literal -offset indent -/sbin/gpart add -s 512M -t freebsd-ufs da0 -.Ed -.Pp -Create a 15GB-sized -.Cm freebsd-ufs -partition to contain a UFS filesystem and aligned on 4KB boundaries: -.Bd -literal -offset indent -/sbin/gpart add -s 15G -t freebsd-ufs -a 4k da0 -.Ed -.Pp -After creating all required partitions, embed bootstrap code into them: -.Bd -literal -offset indent -/sbin/gpart bootcode -p /boot/boot1 da0 -.Ed .Ss Deleting Partitions and Destroying the Partitioning Scheme If a .Em "Device busy" diff --git a/share/man/man4/geom.4 b/share/man/man4/geom.4 index 91ba9360ec3b..cb8f23aca7f3 100644 --- a/share/man/man4/geom.4 +++ b/share/man/man4/geom.4 @@ -34,7 +34,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 27, 2023 +.Dd July 26, 2023 .Dt GEOM 4 .Os .Sh NAME @@ -62,7 +62,6 @@ .Cd options GEOM_PART_GPT .Cd options GEOM_PART_LDM .Cd options GEOM_PART_MBR -.Cd options GEOM_PART_VTOC8 .Cd options GEOM_RAID .Cd options GEOM_RAID3 .Cd options GEOM_SHSEC @@ -494,8 +493,6 @@ Use .Cd GEOM_MULTIPATH , .It .Cd GEOM_PART_MBR , -.It -.Cd GEOM_PART_VTOC8 , and .It .Cd GEOM_LABEL diff --git a/stand/common/part.c b/stand/common/part.c index 4ae38bfb7682..90d7855b53ff 100644 --- a/stand/common/part.c +++ b/stand/common/part.c @@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$"); #include <sys/gpt.h> #include <sys/stddef.h> #include <sys/queue.h> -#include <sys/vtoc.h> #include <fs/cd9660/iso.h> @@ -70,7 +69,6 @@ struct pentry { uint8_t bsd; uint8_t mbr; uuid_t gpt; - uint16_t vtoc8; } type; STAILQ_ENTRY(pentry) entry; }; @@ -519,88 +517,6 @@ out: return (table); } -#ifdef LOADER_VTOC8_SUPPORT -static enum partition_type -vtoc8_parttype(uint16_t type) -{ - - switch (type) { - case VTOC_TAG_FREEBSD_SWAP: - return (PART_FREEBSD_SWAP); - case VTOC_TAG_FREEBSD_UFS: - return (PART_FREEBSD_UFS); - case VTOC_TAG_FREEBSD_VINUM: - return (PART_FREEBSD_VINUM); - case VTOC_TAG_FREEBSD_ZFS: - return (PART_FREEBSD_ZFS); - } - return (PART_UNKNOWN); -} - -static struct ptable * -ptable_vtoc8read(struct ptable *table, void *dev, diskread_t dread) -{ - struct pentry *entry; - struct vtoc8 *dl; - uint8_t *buf; - uint16_t sum, heads, sectors; - int i; - - if (table->sectorsize != sizeof(struct vtoc8)) - return (table); - buf = malloc(table->sectorsize); - if (buf == NULL) - return (table); - if (dread(dev, buf, 1, 0) != 0) { - DPRINTF("read failed"); - ptable_close(table); - table = NULL; - goto out; - } - dl = (struct vtoc8 *)buf; - /* Check the sum */ - for (i = sum = 0; i < sizeof(struct vtoc8); i += sizeof(sum)) - sum ^= be16dec(buf + i); - if (sum != 0) { - DPRINTF("incorrect checksum"); - goto out; - } - if (be16toh(dl->nparts) != VTOC8_NPARTS) { - DPRINTF("invalid number of entries"); - goto out; - } - sectors = be16toh(dl->nsecs); - heads = be16toh(dl->nheads); - if (sectors * heads == 0) { - DPRINTF("invalid geometry"); - goto out; - } - DPRINTF("VTOC8 detected"); - for (i = 0; i < VTOC8_NPARTS; i++) { - dl->part[i].tag = be16toh(dl->part[i].tag); - if (i == VTOC_RAW_PART || - dl->part[i].tag == VTOC_TAG_UNASSIGNED) - continue; - entry = malloc(sizeof(*entry)); - if (entry == NULL) - break; - entry->part.start = be32toh(dl->map[i].cyl) * heads * sectors; - entry->part.end = be32toh(dl->map[i].nblks) + - entry->part.start - 1; - entry->part.type = vtoc8_parttype(dl->part[i].tag); - entry->part.index = i; /* starts from zero */ - entry->type.vtoc8 = dl->part[i].tag; - STAILQ_INSERT_TAIL(&table->entries, entry, entry); - DPRINTF("new VTOC8 partition added"); - } - table->type = PTABLE_VTOC8; -out: - free(buf); - return (table); - -} -#endif /* LOADER_VTOC8_SUPPORT */ - #define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / table->sectorsize) static struct ptable * @@ -678,16 +594,6 @@ ptable_open(void *dev, uint64_t sectors, uint16_t sectorsize, } else if (table->type == PTABLE_ISO9660) goto out; -#ifdef LOADER_VTOC8_SUPPORT - if (be16dec(buf + offsetof(struct vtoc8, magic)) == VTOC_MAGIC) { - if (ptable_vtoc8read(table, dev, dread) == NULL) { - /* Read error. */ - table = NULL; - goto out; - } else if (table->type == PTABLE_VTOC8) - goto out; - } -#endif /* Check the BSD label. */ if (ptable_bsdread(table, dev, dread) == NULL) { /* Read error. */ table = NULL; @@ -928,12 +834,6 @@ ptable_iterate(const struct ptable *table, void *arg, ptable_iterate_t *iter) if (table->type == PTABLE_GPT) sprintf(name, "p%d", entry->part.index); else -#endif -#ifdef LOADER_VTOC8_SUPPORT - if (table->type == PTABLE_VTOC8) - sprintf(name, "%c", (uint8_t) 'a' + - entry->part.index); - else #endif if (table->type == PTABLE_BSD) sprintf(name, "%c", (uint8_t) 'a' + diff --git a/stand/common/part.h b/stand/common/part.h index b991ae3c381c..68acce22cb06 100644 --- a/stand/common/part.h +++ b/stand/common/part.h @@ -36,7 +36,6 @@ enum ptable_type { PTABLE_BSD, PTABLE_MBR, PTABLE_GPT, - PTABLE_VTOC8, PTABLE_ISO9660 }; diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 895bdd0e2129..7558ccb8d920 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -174,7 +174,6 @@ options GEOM_PART_EBR # Extended Boot Records options GEOM_PART_GPT # GPT partitioning options GEOM_PART_LDM # Logical Disk Manager options GEOM_PART_MBR # MBR partitioning -options GEOM_PART_VTOC8 # SMI VTOC8 disk label options GEOM_RAID # Soft RAID functionality. options GEOM_RAID3 # RAID3 functionality. options GEOM_SHSEC # Shared secret. diff --git a/sys/conf/files b/sys/conf/files index 0d5372dfedc6..6774be310f84 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3661,7 +3661,6 @@ geom/part/g_part_ebr.c optional geom_part_ebr geom/part/g_part_gpt.c optional geom_part_gpt geom/part/g_part_ldm.c optional geom_part_ldm geom/part/g_part_mbr.c optional geom_part_mbr -geom/part/g_part_vtoc8.c optional geom_part_vtoc8 geom/raid/g_raid.c optional geom_raid geom/raid/g_raid_ctl.c optional geom_raid geom/raid/g_raid_md_if.m optional geom_raid diff --git a/sys/conf/options b/sys/conf/options index 78d712b7cdbb..c06060f4bea0 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -133,7 +133,6 @@ GEOM_PART_EBR opt_geom.h GEOM_PART_GPT opt_geom.h GEOM_PART_LDM opt_geom.h GEOM_PART_MBR opt_geom.h -GEOM_PART_VTOC8 opt_geom.h GEOM_RAID opt_geom.h GEOM_RAID3 opt_geom.h GEOM_SHSEC opt_geom.h diff --git a/sys/geom/part/g_part_vtoc8.c b/sys/geom/part/g_part_vtoc8.c deleted file mode 100644 index 37ee7cf1c030..000000000000 --- a/sys/geom/part/g_part_vtoc8.c +++ /dev/null @@ -1,604 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2008 Marcel Moolenaar - * 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 AUTHOR ``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 AUTHOR 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 <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/bio.h> -#include <sys/endian.h> -#include <sys/kernel.h> -#include <sys/kobj.h> -#include <sys/limits.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/mutex.h> -#include <sys/queue.h> -#include <sys/sbuf.h> -#include <sys/systm.h> -#include <sys/sysctl.h> -#include <sys/vtoc.h> -#include <geom/geom.h> -#include <geom/geom_int.h> -#include <geom/part/g_part.h> - -#include "g_part_if.h" - -FEATURE(geom_part_vtoc8, "GEOM partitioning class for SMI VTOC8 disk labels"); - -struct g_part_vtoc8_table { - struct g_part_table base; - struct vtoc8 vtoc; - uint32_t secpercyl; -}; - -static int g_part_vtoc8_add(struct g_part_table *, struct g_part_entry *, - struct g_part_parms *); -static int g_part_vtoc8_create(struct g_part_table *, struct g_part_parms *); -static int g_part_vtoc8_destroy(struct g_part_table *, struct g_part_parms *); -static void g_part_vtoc8_dumpconf(struct g_part_table *, - struct g_part_entry *, struct sbuf *, const char *); -static int g_part_vtoc8_dumpto(struct g_part_table *, struct g_part_entry *); -static int g_part_vtoc8_modify(struct g_part_table *, struct g_part_entry *, - struct g_part_parms *); -static const char *g_part_vtoc8_name(struct g_part_table *, - struct g_part_entry *, char *, size_t); -static int g_part_vtoc8_probe(struct g_part_table *, struct g_consumer *); -static int g_part_vtoc8_read(struct g_part_table *, struct g_consumer *); -static const char *g_part_vtoc8_type(struct g_part_table *, - struct g_part_entry *, char *, size_t); -static int g_part_vtoc8_write(struct g_part_table *, struct g_consumer *); -static int g_part_vtoc8_resize(struct g_part_table *, struct g_part_entry *, - struct g_part_parms *); - -static kobj_method_t g_part_vtoc8_methods[] = { - KOBJMETHOD(g_part_add, g_part_vtoc8_add), - KOBJMETHOD(g_part_create, g_part_vtoc8_create), - KOBJMETHOD(g_part_destroy, g_part_vtoc8_destroy), - KOBJMETHOD(g_part_dumpconf, g_part_vtoc8_dumpconf), - KOBJMETHOD(g_part_dumpto, g_part_vtoc8_dumpto), - KOBJMETHOD(g_part_modify, g_part_vtoc8_modify), - KOBJMETHOD(g_part_resize, g_part_vtoc8_resize), - KOBJMETHOD(g_part_name, g_part_vtoc8_name), - KOBJMETHOD(g_part_probe, g_part_vtoc8_probe), - KOBJMETHOD(g_part_read, g_part_vtoc8_read), - KOBJMETHOD(g_part_type, g_part_vtoc8_type), - KOBJMETHOD(g_part_write, g_part_vtoc8_write), - { 0, 0 } -}; - -static struct g_part_scheme g_part_vtoc8_scheme = { - "VTOC8", - g_part_vtoc8_methods, - sizeof(struct g_part_vtoc8_table), - .gps_entrysz = sizeof(struct g_part_entry), - .gps_minent = VTOC8_NPARTS, - .gps_maxent = VTOC8_NPARTS, -}; -G_PART_SCHEME_DECLARE(g_part_vtoc8); -MODULE_VERSION(geom_part_vtoc8, 0); - -static int -vtoc8_parse_type(const char *type, uint16_t *tag) -{ - const char *alias; - char *endp; - long lt; - - if (type[0] == '!') { - lt = strtol(type + 1, &endp, 0); - if (type[1] == '\0' || *endp != '\0' || lt <= 0 || - lt >= 65536) - return (EINVAL); - *tag = (uint16_t)lt; - return (0); - } - alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_NANDFS); - if (!strcasecmp(type, alias)) { - *tag = VTOC_TAG_FREEBSD_NANDFS; - return (0); - } - alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP); - if (!strcasecmp(type, alias)) { - *tag = VTOC_TAG_FREEBSD_SWAP; - return (0); - } - alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_UFS); - if (!strcasecmp(type, alias)) { - *tag = VTOC_TAG_FREEBSD_UFS; - return (0); - } - alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_VINUM); - if (!strcasecmp(type, alias)) { - *tag = VTOC_TAG_FREEBSD_VINUM; - return (0); - } - alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_ZFS); - if (!strcasecmp(type, alias)) { - *tag = VTOC_TAG_FREEBSD_ZFS; - return (0); - } - return (EINVAL); -} - -static int -vtoc8_align(struct g_part_vtoc8_table *table, uint64_t *start, uint64_t *size) -{ - - if (*size < table->secpercyl) - return (EINVAL); - if (start != NULL && (*start % table->secpercyl)) { - *size += (*start % table->secpercyl) - table->secpercyl; - *start -= (*start % table->secpercyl) - table->secpercyl; - } - if (*size % table->secpercyl) - *size -= (*size % table->secpercyl); - if (*size < table->secpercyl) - return (EINVAL); - return (0); -} - -static int -g_part_vtoc8_add(struct g_part_table *basetable, struct g_part_entry *entry, - struct g_part_parms *gpp) -{ - struct g_part_vtoc8_table *table; - int error, index; - uint64_t start, size; - uint16_t tag; - - if (gpp->gpp_parms & G_PART_PARM_LABEL) - return (EINVAL); - - error = vtoc8_parse_type(gpp->gpp_type, &tag); - if (error) - return (error); - - table = (struct g_part_vtoc8_table *)basetable; - index = entry->gpe_index - 1; - start = gpp->gpp_start; - size = gpp->gpp_size; - if (vtoc8_align(table, &start, &size) != 0) - return (EINVAL); - - KASSERT(entry->gpe_start <= start, (__func__)); - KASSERT(entry->gpe_end >= start + size - 1, (__func__)); - entry->gpe_start = start; - entry->gpe_end = start + size - 1; - - be16enc(&table->vtoc.part[index].tag, tag); - be16enc(&table->vtoc.part[index].flag, 0); - be32enc(&table->vtoc.timestamp[index], 0); - be32enc(&table->vtoc.map[index].cyl, start / table->secpercyl); - be32enc(&table->vtoc.map[index].nblks, size); - return (0); -} - -static int -g_part_vtoc8_create(struct g_part_table *basetable, struct g_part_parms *gpp) -{ - struct g_provider *pp; - struct g_part_entry *entry; - struct g_part_vtoc8_table *table; - uint64_t msize; - uint32_t acyls, ncyls, pcyls; - - pp = gpp->gpp_provider; - - if (pp->sectorsize < sizeof(struct vtoc8)) - return (ENOSPC); - if (pp->sectorsize > sizeof(struct vtoc8)) - return (ENXIO); - - table = (struct g_part_vtoc8_table *)basetable; - - msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); - table->secpercyl = basetable->gpt_sectors * basetable->gpt_heads; - pcyls = msize / table->secpercyl; - acyls = 2; - ncyls = pcyls - acyls; - msize = ncyls * table->secpercyl; - - snprintf(table->vtoc.ascii, sizeof(table->vtoc.ascii), - "FreeBSD%lldM cyl %u alt %u hd %u sec %u", - (long long)(msize / 2048), ncyls, acyls, basetable->gpt_heads, - basetable->gpt_sectors); - be32enc(&table->vtoc.version, VTOC_VERSION); - be16enc(&table->vtoc.nparts, VTOC8_NPARTS); - be32enc(&table->vtoc.sanity, VTOC_SANITY); - be16enc(&table->vtoc.rpm, 3600); - be16enc(&table->vtoc.physcyls, pcyls); - be16enc(&table->vtoc.ncyls, ncyls); - be16enc(&table->vtoc.altcyls, acyls); - be16enc(&table->vtoc.nheads, basetable->gpt_heads); - be16enc(&table->vtoc.nsecs, basetable->gpt_sectors); - be16enc(&table->vtoc.magic, VTOC_MAGIC); - - basetable->gpt_first = 0; - basetable->gpt_last = msize - 1; - basetable->gpt_isleaf = 1; - - entry = g_part_new_entry(basetable, VTOC_RAW_PART + 1, - basetable->gpt_first, basetable->gpt_last); - entry->gpe_internal = 1; - be16enc(&table->vtoc.part[VTOC_RAW_PART].tag, VTOC_TAG_BACKUP); - be32enc(&table->vtoc.map[VTOC_RAW_PART].nblks, msize); - return (0); -} - -static int -g_part_vtoc8_destroy(struct g_part_table *basetable, struct g_part_parms *gpp) -{ - - /* Wipe the first sector to clear the partitioning. */ - basetable->gpt_smhead |= 1; - return (0); -} - -static void -g_part_vtoc8_dumpconf(struct g_part_table *basetable, - struct g_part_entry *entry, struct sbuf *sb, const char *indent) -{ - struct g_part_vtoc8_table *table; - - table = (struct g_part_vtoc8_table *)basetable; - if (indent == NULL) { - /* conftxt: libdisk compatibility */ - sbuf_printf(sb, " xs SUN sc %u hd %u alt %u", - be16dec(&table->vtoc.nsecs), be16dec(&table->vtoc.nheads), - be16dec(&table->vtoc.altcyls)); - } else if (entry != NULL) { - /* confxml: partition entry information */ - sbuf_printf(sb, "%s<rawtype>%u</rawtype>\n", indent, - be16dec(&table->vtoc.part[entry->gpe_index - 1].tag)); - } else { - /* confxml: scheme information */ - } -} - -static int -g_part_vtoc8_dumpto(struct g_part_table *basetable, - struct g_part_entry *entry) -{ - struct g_part_vtoc8_table *table; - uint16_t tag; - - /* - * Allow dumping to a swap partition or a partition that - * has no type. - */ - table = (struct g_part_vtoc8_table *)basetable; - tag = be16dec(&table->vtoc.part[entry->gpe_index - 1].tag); - return ((tag == 0 || tag == VTOC_TAG_FREEBSD_SWAP || - tag == VTOC_TAG_SWAP) ? 1 : 0); -} - -static int -g_part_vtoc8_modify(struct g_part_table *basetable, - struct g_part_entry *entry, struct g_part_parms *gpp) -{ - struct g_part_vtoc8_table *table; - int error; - uint16_t tag; - - if (gpp->gpp_parms & G_PART_PARM_LABEL) - return (EINVAL); - - table = (struct g_part_vtoc8_table *)basetable; - if (gpp->gpp_parms & G_PART_PARM_TYPE) { - error = vtoc8_parse_type(gpp->gpp_type, &tag); - if (error) - return(error); - - be16enc(&table->vtoc.part[entry->gpe_index - 1].tag, tag); - } - return (0); -} - -static int -vtoc8_set_rawsize(struct g_part_table *basetable, struct g_provider *pp) -{ - struct g_part_vtoc8_table *table; - struct g_part_entry *baseentry; - off_t msize; - uint32_t acyls, ncyls, pcyls; - - table = (struct g_part_vtoc8_table *)basetable; - msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX); - pcyls = msize / table->secpercyl; - if (pcyls > UINT16_MAX) *** 614 LINES SKIPPED ***