Consolidate disk geometry fiddling, turning -l/-c/-h/-s values into MBR
authorkrw <krw@openbsd.org>
Thu, 15 Jul 2021 21:23:54 +0000 (21:23 +0000)
committerkrw <krw@openbsd.org>
Thu, 15 Jul 2021 21:23:54 +0000 (21:23 +0000)
partition geometry info, into DISK_open(). Resulting in clearer logic.

No intentional functional change.

sbin/fdisk/disk.c
sbin/fdisk/disk.h
sbin/fdisk/fdisk.c

index 880aa0b..d742941 100644 (file)
@@ -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");
 }
 
 /*
index 465449e..fe6bee2 100644 (file)
@@ -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);
index 21670d0..d90fb9d 100644 (file)
@@ -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);