Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/fdisk Add support for partition being aligned on non-cy...



details:   https://anonhg.NetBSD.org/src/rev/41e9abaa4dae
branches:  trunk
changeset: 750274:41e9abaa4dae
user:      dsl <dsl%NetBSD.org@localhost>
date:      Tue Dec 22 21:55:12 2009 +0000

description:
Add support for partition being aligned on non-cylinder boundaries.
Info can be specified with -A parameter.
Default is based on how the first partition is defined.
For empty disks larger than 128GB (arbitrary figure) use 1MB alignment.

diffstat:

 sbin/fdisk/fdisk.c |  123 ++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 84 insertions(+), 39 deletions(-)

diffs (272 lines):

diff -r 35e6edbcc44e -r 41e9abaa4dae sbin/fdisk/fdisk.c
--- a/sbin/fdisk/fdisk.c        Tue Dec 22 21:04:37 2009 +0000
+++ b/sbin/fdisk/fdisk.c        Tue Dec 22 21:55:12 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fdisk.c,v 1.128 2009/12/22 21:04:37 dsl Exp $ */
+/*     $NetBSD: fdisk.c,v 1.129 2009/12/22 21:55:12 dsl Exp $ */
 
 /*
  * Mach Operating System
@@ -39,7 +39,7 @@
 #include <sys/cdefs.h>
 
 #ifndef lint
-__RCSID("$NetBSD: fdisk.c,v 1.128 2009/12/22 21:04:37 dsl Exp $");
+__RCSID("$NetBSD: fdisk.c,v 1.129 2009/12/22 21:55:12 dsl Exp $");
 #endif /* not lint */
 
 #define MBRPTYPENAMES
@@ -150,12 +150,12 @@
 char *boot_path = 0;                   /* name of file we actually opened */
 
 #ifdef BOOTSEL
-
-#define OPTIONS                        "0123BFSafiluvs:b:c:E:r:w:t:T:"
+#define BOOTSEL_OPTIONS        "B"
 #else
+#define BOOTSEL_OPTIONS        
 #define change_part(e, p, id, st, sz, bm) change__part(e, p, id, st, sz)
-#define OPTIONS                        "0123FSafiluvs:b:c:E:r:w:"
 #endif
+#define OPTIONS        BOOTSEL_OPTIONS "0123FSafiluvA:b:c:E:r:s:w:"
 
 /*
  * Disk geometry and partition alignment.
@@ -215,8 +215,8 @@
 int partition = -1;
 
 /* Alignment of partition, and offset if first sector unusable */
-#define        ptn_alignment   dos_cylindersectors
-#define        ptn_offset      dos_sectors
+unsigned int ptn_alignment;    /* default dos_cylindersectors */
+unsigned int ptn_offset;       /* default dos_sectors */
 
 int fd = -1, wfd = -1, *rfd = &fd;
 char *disk_file = NULL;
@@ -264,16 +264,17 @@
 int    read_boot(const char *, void *, size_t, int);
 void   init_sector0(int);
 void   intuit_translated_geometry(void);
-void   get_geometry(void);
+void   get_bios_geometry(void);
 void   get_extended_ptn(void);
+static void get_ptn_alignmemt(void);
 #if (defined(__i386__) || defined(__x86_64__)) && !HAVE_NBTOOL_CONFIG_H
 void   get_diskname(const char *, char *, size_t);
 #endif /* (defined(__i386__) || defined(__x86_64__)) && !HAVE_NBTOOL_CONFIG_H */
 int    change_part(int, int, int, daddr_t, daddr_t, char *);
-void   print_params(void);
+void   print_geometry(void);
 int    first_active(void);
 void   change_active(int);
-void   get_params_to_use(void);
+void   change_bios_geometry(void);
 void   dos(int, unsigned char *, unsigned char *, unsigned char *);
 int    open_disk(int);
 int    read_disk(daddr_t, void *);
@@ -287,7 +288,7 @@
 int64_t        decimal(const char *, int64_t, int, int64_t, int64_t);
 #define DEC_SEC                1               /* asking for a sector number */
 #define        DEC_RND         2               /* round to end of first track */
-#define        DEC_RND_0       4               /* round 0 to size of a track */
+#define        DEC_RND_0       4               /* convert 0 to size of a track */
 #define DEC_RND_DOWN   8               /* subtract 1 track */
 #define DEC_RND_DOWN_2 16              /* subtract 2 tracks */
 void   string(const char *, int, char *);
@@ -341,7 +342,7 @@
        v_flag = 0;
        E_flag = 0;
        csysid = cstart = csize = 0;
-       while ((ch = getopt(argc, argv, OPTIONS)) != -1)
+       while ((ch = getopt(argc, argv, OPTIONS)) != -1) {
                switch (ch) {
                case '0':
                        partition = 0;
@@ -415,6 +416,15 @@
                        if (b_cyl > MAXCYL)
                                b_cyl = MAXCYL;
                        break;
+               case 'A':       /* Partition alignment[/offset] */
+                       if (sscanf(optarg, "%u/%u%n", &ptn_alignment,
+                                   &ptn_offset, &n) < 1
+                           || optarg[n] != 0
+                           || ptn_offset > ptn_alignment)
+                               errx(1, "Bad argument to the -A flag.");
+                       if (ptn_offset == 0)
+                               ptn_offset = ptn_alignment;
+                       break;
                case 'c':       /* file/directory containing boot code */
                        if (strchr(optarg, '/') != NULL &&
                            stat(optarg, &sb) == 0 &&
@@ -442,6 +452,7 @@
                default:
                        usage();
                }
+       }
        argc -= optind;
        argv += optind;
 
@@ -489,11 +500,17 @@
        read_gpt(GPT_HDR_BLKNO, &gpt1);
        read_gpt(disksectors - 1, &gpt2);
 
-#if (defined(__i386__) || defined(__x86_64__)) && !HAVE_NBTOOL_CONFIG_H
-       get_geometry();
-#else
-       intuit_translated_geometry();
-#endif
+       if (b_flag) {
+               dos_cylinders = b_cyl;
+               dos_heads = b_head;
+               dos_sectors = b_sec;
+       } else {
+               get_bios_geometry();
+       }
+
+       if (ptn_alignment == 0)
+               get_ptn_alignmemt();
+
        get_extended_ptn();
 
 #ifdef BOOTSEL
@@ -503,11 +520,11 @@
        if (E_flag && !u_flag && partition >= ext.num_ptn)
                errx(1, "Extended partition %d is not defined.", partition);
 
-       if (u_flag && (!f_flag || b_flag))
-               get_params_to_use();
-
        /* Do the update stuff! */
        if (u_flag) {
+               if (!f_flag && !b_flag)
+                       change_bios_geometry();
+
                if (s_flag)
                        change_part(E_flag, partition, csysid, cstart, csize,
                                cbootmenu);
@@ -527,11 +544,12 @@
                                prompt = change_part(chg_ext, part, 0, 0, 0, 0);
                        } while (partition == -1);
                }
-       } else
+       } else {
                if (!i_flag && !B_flag) {
-                       print_params();
+                       print_geometry();
                        print_s0(partition);
                }
+       }
 
        if (a_flag && !E_flag)
                change_active(partition);
@@ -1157,9 +1175,42 @@
        diskname[len] = 0;
 }
 
+static void
+get_ptn_alignmemt(void)
+{
+       struct mbr_partition *partp = &mboot.mbr_parts[0];
+       uint32_t ptn_0_base, ptn_0_limit;
+
+       /* Default to using 'traditional' cylinder alignment */
+       ptn_alignment = dos_cylindersectors;
+       ptn_offset = dos_sectors;
+
+       if (partp->mbrp_type != 0) {
+               /* Try to copy alignment of first partition */
+               ptn_0_base = le32toh(partp->mbrp_start);
+               ptn_0_limit = ptn_0_base + le32toh(partp->mbrp_size);
+               if (!(ptn_0_limit & 2047)) {
+                       /* Partition ends on a 1MB boundary, align to 1MB */
+                       ptn_alignment = 2048;
+                       if (ptn_0_base <= 2048
+                           && !(ptn_0_base & (ptn_0_base - 1))) {
+                               /* ptn_base is a power of 2, use it */
+                               ptn_offset = ptn_0_base;
+                       }
+               }
+       } else {
+               /* Use 1MB alignment for large disks */
+               if (disksectors > 2048 * 1024 * 128) {
+                       ptn_alignment = 2048;
+                       ptn_offset = 2048;
+               }
+       }
+}
+
 void
-get_geometry(void)
+get_bios_geometry(void)
 {
+#if (defined(__i386__) || defined(__x86_64__)) && !HAVE_NBTOOL_CONFIG_H
        int mib[2], i;
        size_t len;
        struct biosdisk_info *bip;
@@ -1203,6 +1254,7 @@
                }
        }
  out:
+#endif
        /* Allright, allright, make a stupid guess.. */
        intuit_translated_geometry();
 }
@@ -2232,7 +2284,7 @@
 }
 
 void
-print_params(void)
+print_geometry(void)
 {
 
        if (sh_flag) {
@@ -2256,6 +2308,8 @@
            "(%d sectors/cylinder)\ntotal sectors: %"PRIdaddr"\n\n",
            dos_cylinders, dos_heads, dos_sectors, dos_cylindersectors,
            dos_disksectors);
+       printf("Partitions aligned to %d sector boundaries, offset %d\n\n",
+           ptn_alignment, ptn_offset);
 }
 
 /* Find the first active partition, else return MBR_PART_COUNT */
@@ -2305,26 +2359,17 @@
 }
 
 void
-get_params_to_use(void)
+change_bios_geometry(void)
 {
-#if defined(__i386__) || defined(__x86_64__)
-       struct biosdisk_info *bip;
-       int i;
-#endif
-
-       if (b_flag) {
-               dos_cylinders = b_cyl;
-               dos_heads = b_head;
-               dos_sectors = b_sec;
-               return;
-       }
-
-       print_params();
+       print_geometry();
        if (!yesno("Do you want to change our idea of what BIOS thinks?"))
                return;
 
 #if (defined(__i386__) || defined(__x86_64__)) && !HAVE_NBTOOL_CONFIG_H
        if (dl != NULL) {
+               struct biosdisk_info *bip;
+               int i;
+
                for (i = 0; i < dl->dl_nbiosdisks; i++) {
                        if (i == 0)
                                printf("\nGeometries of known disks:\n");
@@ -2345,7 +2390,7 @@
                                        dos_heads, 0, 0, MAXHEAD);
                dos_sectors = decimal("BIOS's idea of #sectors",
                                        dos_sectors, 0, 1, MAXSECTOR);
-               print_params();
+               print_geometry();
        } while (!yesno("Are you happy with this choice?"));
 }
 



Home | Main Index | Thread Index | Old Index