diff options
author | des <des@FreeBSD.org> | 2016-08-19 07:05:34 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2016-08-19 07:05:34 +0000 |
commit | 6e1863a39719b3bc7691734b79aef17c85d4a708 (patch) | |
tree | cc4bef6e7f795fa8eaf4529233da65ae6f283958 /usr.sbin | |
parent | 57203705c2226203d72b3ea47327f92fd3d72681 (diff) | |
download | FreeBSD-src-6e1863a39719b3bc7691734b79aef17c85d4a708.zip FreeBSD-src-6e1863a39719b3bc7691734b79aef17c85d4a708.tar.gz |
MFH (r304142): ensure stripe size is non-zero multiple of 4096
PR: 211361
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bsdinstall/partedit/gpart_ops.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/usr.sbin/bsdinstall/partedit/gpart_ops.c b/usr.sbin/bsdinstall/partedit/gpart_ops.c index 04c8cea..89d7529 100644 --- a/usr.sbin/bsdinstall/partedit/gpart_ops.c +++ b/usr.sbin/bsdinstall/partedit/gpart_ops.c @@ -795,6 +795,7 @@ gpart_max_free(struct ggeom *geom, intmax_t *npartstart) { 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, intmax_t *npartstart) 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; } |