Author: des
Date: Mon Aug 15 09:30:21 2016
New Revision: 304142
URL: https://svnweb.freebsd.org/changeset/base/304142

Log:
  Ensure that the sector size is a multiple of 4096 to avoid creating
  unaligned partitions when the actual sector size is hidden from us.
  
  PR:           211361
  MFC after:    3 days

Modified:
  head/usr.sbin/bsdinstall/partedit/gpart_ops.c

Modified: head/usr.sbin/bsdinstall/partedit/gpart_ops.c
==============================================================================
--- head/usr.sbin/bsdinstall/partedit/gpart_ops.c       Mon Aug 15 09:27:15 
2016        (r304141)
+++ head/usr.sbin/bsdinstall/partedit/gpart_ops.c       Mon Aug 15 09:30:21 
2016        (r304142)
@@ -795,6 +795,7 @@ gpart_max_free(struct ggeom *geom, intma
 {
        struct gconfig *gc;
        struct gprovider *pp, **providers;
+       intmax_t sectorsize, stripesize, offset;
        intmax_t lastend;
        intmax_t start, end;
        intmax_t maxsize, maxstart;
@@ -845,12 +846,25 @@ gpart_max_free(struct ggeom *geom, intma
 
        pp = LIST_FIRST(&geom->lg_consumer)->lg_provider;
 
-       /* Compute beginning of new partition and maximum available space */
-       if (pp->lg_stripesize > 0 &&
-           (maxstart*pp->lg_sectorsize % pp->lg_stripesize) != 0) {
-               intmax_t offset = (pp->lg_stripesize -
-                   ((maxstart*pp->lg_sectorsize) % pp->lg_stripesize)) /
-                   pp->lg_sectorsize;
+       /*
+        * Round the start and size of the largest available space up to
+        * the nearest multiple of the adjusted stripe size.
+        *
+        * The adjusted stripe size is the least common multiple of the
+        * actual stripe size, or the sector size if no stripe size was
+        * reported, and 4096.  The reason for this is that contemporary
+        * disks often have 4096-byte physical sectors but report 512
+        * bytes instead for compatibility with older / broken operating
+        * systems and BIOSes.  For the same reasons, virtualized storage
+        * may also report a 512-byte stripe size, or none at all.
+        */
+       sectorsize = pp->lg_sectorsize;
+       if ((stripesize = pp->lg_stripesize) == 0)
+               stripesize = sectorsize;
+       while (stripesize % 4096 != 0)
+               stripesize *= 2;
+       if ((offset = maxstart * sectorsize % stripesize) != 0) {
+               offset = (stripesize - offset) / sectorsize;
                maxstart += offset;
                maxsize -= offset;
        }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to