diff options
-rw-r--r-- | sbin/fdisk/disk.c | 65 | ||||
-rw-r--r-- | sbin/fdisk/disk.h | 4 | ||||
-rw-r--r-- | sbin/fdisk/fdisk.c | 54 |
3 files changed, 61 insertions, 62 deletions
diff --git a/sbin/fdisk/disk.c b/sbin/fdisk/disk.c index 880aa0be2ba..d742941505e 100644 --- a/sbin/fdisk/disk.c +++ b/sbin/fdisk/disk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: disk.c,v 1.63 2021/07/13 15:03:34 krw Exp $ */ +/* $OpenBSD: disk.c,v 1.64 2021/07/15 21:23:54 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -16,7 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <sys/types.h> +#include <sys/param.h> /* DEV_BSIZE */ #include <sys/ioctl.h> #include <sys/dkio.h> #include <sys/stat.h> @@ -28,6 +28,7 @@ #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #include <util.h> @@ -38,45 +39,53 @@ struct disk disk; struct disklabel dl; void -DISK_open(const int rw) +DISK_open(const char *name, const int oflags) { struct stat st; uint64_t sz, spc; - disk.dk_fd = opendev(disk.dk_name, rw ? O_RDWR : O_RDONLY, OPENDEV_PART, - NULL); + disk.dk_name = strdup(name); + if (disk.dk_name == NULL) + err(1, "DISK_Open('%s')", name); + + disk.dk_fd = opendev(disk.dk_name, oflags, OPENDEV_PART, NULL); if (disk.dk_fd == -1) err(1, "%s", disk.dk_name); if (fstat(disk.dk_fd, &st) == -1) err(1, "%s", disk.dk_name); if (!S_ISCHR(st.st_mode)) errx(1, "%s is not a character device", disk.dk_name); - - /* Get label geometry. */ - if (ioctl(disk.dk_fd, DIOCGPDINFO, &dl) == -1) { - warn("DIOCGPDINFO"); + if (ioctl(disk.dk_fd, DIOCGPDINFO, &dl) == -1) + err(1, "DIOCGPDINFO"); + + unit_types[SECTORS].ut_conversion = dl.d_secsize; + + /* Set geometry to use in MBR partitions. */ + if (disk.dk_size > 0) { + /* -l has set disk size. */ + sz = DL_BLKTOSEC(&dl, disk.dk_size); + disk.dk_heads = 1; + disk.dk_sectors = 64; + } else if (disk.dk_cylinders > 0) { + /* -c/-h/-c has set disk geometry. */ + sz = disk.dk_cylinders * disk.dk_heads * disk.dk_sectors; + sz = DL_BLKTOSEC(&dl, sz); + disk.dk_sectors = DL_BLKTOSEC(&dl, disk.dk_sectors); } else { - unit_types[SECTORS].ut_conversion = dl.d_secsize; - if (disk.dk_size == 0) { - /* -l or -c/-h/-s not used. Use disklabel info. */ - disk.dk_cylinders = dl.d_ncylinders; - disk.dk_heads = dl.d_ntracks; - disk.dk_sectors = dl.d_nsectors; - /* MBR handles only first UINT32_MAX sectors. */ - spc = (uint64_t)disk.dk_heads * disk.dk_sectors; - sz = DL_GETDSIZE(&dl); - if (sz > UINT32_MAX) { - disk.dk_cylinders = UINT32_MAX / spc; - disk.dk_size = disk.dk_cylinders * spc; - } else - disk.dk_size = sz; - } + sz = DL_GETDSIZE(&dl); + disk.dk_heads = dl.d_ntracks; + disk.dk_sectors = dl.d_nsectors; } - if (disk.dk_size == 0 || disk.dk_cylinders == 0 || disk.dk_heads == 0 || - disk.dk_sectors == 0 || unit_types[SECTORS].ut_conversion == 0) - errx(1, "Can't get disk geometry, please use [-chs] or [-l]" - "to specify."); + if (sz > UINT32_MAX) + sz = UINT32_MAX; /* MBR knows nothing > UINT32_MAX. */ + + spc = disk.dk_heads * disk.dk_sectors; + disk.dk_cylinders = sz / spc; + disk.dk_size = disk.dk_cylinders * spc; + + if (disk.dk_size == 0) + errx(1, "dk_size == 0"); } /* diff --git a/sbin/fdisk/disk.h b/sbin/fdisk/disk.h index 465449e2ed7..fe6bee275a4 100644 --- a/sbin/fdisk/disk.h +++ b/sbin/fdisk/disk.h @@ -1,4 +1,4 @@ -/* $OpenBSD: disk.h,v 1.27 2021/07/13 15:03:34 krw Exp $ */ +/* $OpenBSD: disk.h,v 1.28 2021/07/15 21:23:54 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -31,7 +31,7 @@ struct disk { /* Align partition starts/sizes on 32K-byte boundaries. */ #define BLOCKALIGNMENT 64 -void DISK_open(const int); +void DISK_open(const char *, const int); int DISK_printgeometry(const char *); char *DISK_readsector(const uint64_t); int DISK_writesector(const char *, const uint64_t); diff --git a/sbin/fdisk/fdisk.c b/sbin/fdisk/fdisk.c index 21670d08aaa..d90fb9daf10 100644 --- a/sbin/fdisk/fdisk.c +++ b/sbin/fdisk/fdisk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fdisk.c,v 1.119 2021/07/12 14:06:19 krw Exp $ */ +/* $OpenBSD: fdisk.c,v 1.120 2021/07/15 21:23:54 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -75,8 +75,7 @@ main(int argc, char *argv[]) unsigned int bps; int e_flag = 0, g_flag = 0, i_flag = 0, u_flag = 0; int verbosity = TERSE; - int c_arg = 0, h_arg = 0, s_arg = 0; - uint32_t l_arg = 0; + int oflags = O_RDONLY; char *query; while ((ch = getopt(argc, argv, "Aiegpuvf:c:h:s:l:b:y")) != -1) { @@ -85,40 +84,41 @@ main(int argc, char *argv[]) switch(ch) { case 'A': A_flag = 1; + oflags = O_RDWR; break; case 'i': i_flag = 1; + oflags = O_RDWR; break; case 'u': u_flag = 1; + oflags = O_RDWR; break; case 'e': e_flag = 1; + oflags = O_RDWR; break; case 'f': mbrfile = optarg; break; case 'c': - c_arg = strtonum(optarg, 1, 262144, &errstr); + disk.dk_cylinders = strtonum(optarg, 1, 262144, &errstr); if (errstr) errx(1, "Cylinder argument %s [1..262144].", errstr); - disk.dk_cylinders = c_arg; - disk.dk_size = c_arg * h_arg * s_arg; + disk.dk_size = 0; break; case 'h': - h_arg = strtonum(optarg, 1, 256, &errstr); + disk.dk_heads = strtonum(optarg, 1, 256, &errstr); if (errstr) errx(1, "Head argument %s [1..256].", errstr); - disk.dk_heads = h_arg; - disk.dk_size = c_arg * h_arg * s_arg; + disk.dk_size = 0; break; case 's': - s_arg = strtonum(optarg, 1, 63, &errstr); + disk.dk_sectors = strtonum(optarg, 1, 63, &errstr); if (errstr) errx(1, "Sector argument %s [1..63].", errstr); - disk.dk_sectors = s_arg; - disk.dk_size = c_arg * h_arg * s_arg; + disk.dk_size = 0; break; case 'g': g_flag = 1; @@ -127,14 +127,11 @@ main(int argc, char *argv[]) parse_b(optarg, &b_sectors, &b_offset, &b_type); break; case 'l': - l_arg = strtonum(optarg, BLOCKALIGNMENT, UINT32_MAX, &errstr); + disk.dk_size = strtonum(optarg, BLOCKALIGNMENT, UINT32_MAX, &errstr); if (errstr) errx(1, "Block argument %s [%u..%u].", errstr, BLOCKALIGNMENT, UINT32_MAX); - disk.dk_cylinders = l_arg / BLOCKALIGNMENT; - disk.dk_heads = 1; - disk.dk_sectors = BLOCKALIGNMENT; - disk.dk_size = l_arg; + disk.dk_cylinders = disk.dk_heads = disk.dk_sectors = 0; break; case 'y': y_flag = 1; @@ -152,13 +149,15 @@ main(int argc, char *argv[]) /* Argument checking */ if (argc != 1 || (i_flag && u_flag) || (i_flag == 0 && g_flag) || - (b_sectors && !(i_flag || A_flag)) || - ((c_arg | h_arg | s_arg) && !(c_arg && h_arg && s_arg)) || - ((c_arg | h_arg | s_arg) && l_arg)) + (b_sectors && !(i_flag || A_flag))) usage(); - disk.dk_name = argv[0]; - DISK_open(A_flag || i_flag || u_flag || e_flag); + if ((disk.dk_cylinders || disk.dk_heads || disk.dk_sectors) && + (disk.dk_cylinders * disk.dk_heads * disk.dk_sectors == 0)) + usage(); + + DISK_open(argv[0], oflags); + bps = DL_BLKSPERSEC(&dl); if (b_sectors > 0) { if (b_sectors % bps != 0) @@ -168,15 +167,6 @@ main(int argc, char *argv[]) b_sectors = DL_BLKTOSEC(&dl, b_sectors); b_offset = DL_BLKTOSEC(&dl, b_offset); } - if (l_arg > 0) { - if (l_arg % bps != 0) - l_arg += bps - l_arg % bps; - l_arg = DL_BLKTOSEC(&dl, l_arg); - disk.dk_cylinders = l_arg / BLOCKALIGNMENT; - disk.dk_heads = 1; - disk.dk_sectors = BLOCKALIGNMENT; - disk.dk_size = l_arg; - } /* "proc exec" for man page display */ if (pledge("stdio rpath wpath disklabel proc exec", NULL) == -1) @@ -192,7 +182,7 @@ main(int argc, char *argv[]) if (efi != -1) GPT_read(ANYGPT); - if (!(A_flag || i_flag || u_flag || e_flag)) { + if (oflags == O_RDONLY) { if (pledge("stdio", NULL) == -1) err(1, "pledge"); USER_print_disk(verbosity); |