fwsectors and fwheads used to be somehwat arbitrary. However, they are

used to align partitions in gpart. We also try to align partitions by
stripe size when creating new media. Align these two concepts by
making fwsectors the same as the stripe size. Select a sensible number
of heads so we wind up with about 20 cylinders. This number was
selected to keep the rounding effects to a few percent while keeping
the number of cylinder groups low.

Sadly, it is not possible to make these numbers match the numbers used
by SD card readers. There apperas to be much variation between brands
so there's no one universal number. These numbers are also not aligned
to the stripe size, so some performance problems may still be present
when SD cards are created this way.

Also, these numbers will differ from the far less common SD to ATA
adapters, which present a different, but more uniform, set of numbers
that also happened to match the old defaults.

Nothing should change for current users. Any suboptimal performance
caused by misalignment will still be there. gpart will honor the
partitions that aren't on proper boudnaries, but editing the partition
tables may result in different alignments being used than before when
editing things natively.

Ideally, there'd be some way to override these values in the disk
subsystem by the user for the USB adapter use case where all "native"
notions of geometry disappear. This does not implement that.
This commit is contained in:
Warner Losh 2014-10-16 19:52:12 +00:00
parent d98ae07545
commit a5928b20d5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=273180

View File

@ -155,14 +155,36 @@ mmcsd_attach(device_t dev)
d->d_dump = mmcsd_dump;
d->d_name = "mmcsd";
d->d_drv1 = sc;
d->d_maxsize = 4*1024*1024; /* Maximum defined SD card AU size. */
d->d_sectorsize = mmc_get_sector_size(dev);
d->d_maxsize = mmc_get_max_data(dev) * d->d_sectorsize;
d->d_mediasize = (off_t)mmc_get_media_size(dev) * d->d_sectorsize;
d->d_stripeoffset = 0;
d->d_stripesize = mmc_get_erase_sector(dev) * d->d_sectorsize;
d->d_unit = device_get_unit(dev);
d->d_flags = DISKFLAG_CANDELETE;
d->d_delmaxsize = mmc_get_erase_sector(dev) * d->d_sectorsize * 1; /* conservative */
/*
* The d_fw* values are fake. However, layout is aided by making the
* number of fwsectors equal to the erase sectors from the drive since
* we set the stripe size equal to that. We set fwheads such that there
* are ~20 cylinder groups since all values are somewhat arbitrary here
* and this gives good behavior with ffs without wasting too much
* space. Sadly, geom_part wants to round partitions to these
* values. While not bad, in and of itself, the values we present here
* will almost certainly be different then the values that USB SD
* adapters use and there's too much variation between brands to just
* use those values here. Also SD to ATA adapters favor traditional
* ata sizes, which are different again from the USB adapters (which
* favor SCSI values). This rounding leads to a loss of up to 5% of the
* usable space (usually much less, but that's why 20 was selected: to
* limit this effect at a few percent). gpart needs a way to override
* this behavior for situations like this, but doesn't provide
* one. Perhaps this behavior should be tunable as well, but maybe that
* belongs in the disk layer. These values will be much better than
* the default ones.
*/
d->d_fwsectors = mmc_get_erase_sector(dev);
d->d_fwheads = mmc_get_media_size(dev) / (d->d_fwsectors * 20);
strlcpy(d->d_ident, mmc_get_card_sn_string(dev), sizeof(d->d_ident));
strlcpy(d->d_descr, mmc_get_card_id_string(dev), sizeof(d->d_descr));