On Tue, Mar 31, 2009 at 08:13:22PM +0200, frantisek holop wrote:
> first of all, thanks Nick for your time going through
> all of that.  here is my answer.  it is all quite i386
> specific though.
> 
> hmm, on Tue, Mar 24, 2009 at 11:34:38PM -0400, Nick Holland said that
> > I really don't want to ignore what you call an "exotic geometry".
> > A lot of people seem to think there is something "standard" about
> > what you are calling "n/255/63 geometry", but life ain't so
> 
> well, the commercial sector making partitioning software seems
> to disagree here.  the quite popular PartitionMagic comes to my
> mind.  and openbsd itself had a commit in the past to show every
> sd(4) disk using this very same geometry if i am not mistaken.

Also sprach the commit messag for r1.125 of sd.c:

"For devices unwilling or unable to report geometry, change the 'fake'
geometry used to 255 heads and 63 sectors/track from 64 heads and 32
sectors. 255/63 makes the cylinders as large as PC/BIOS compatibility
allows, increasing the size of devices that can be supported."

The sd driver tries to determine the geometry of the disk by reading the
PAGE_REDUCED_GEOMETRY, PAGE_RIGID_GEOMETRY or PAGE_FLEX_GEOMETRY mode
pages. If no coherent information is obtained (or the device is USB in
which case we throw up our hands in despair and don't even try to
read the info) then and only then is a 'default' geometry used.

As the code says:

        /*
         * XXX THINK ABOUT THIS!!  Using values such that sectors * heads *
         * cyls is <= disk_size can lead to wasted space. We need a more
         * careful calculation/validation to make everything work out
         * optimally.
         */
        if (dp->disksize > 0xffffffff && (dp->heads * dp->sectors) < 0xffff) {
                dp->heads = 511;
                dp->sectors = 255;
                cyls = 0;
        } else {
                /*
                 * Use standard geometry values for anything we still don't
                 * know.
                 */
                dp->heads = (heads == 0) ? 255 : heads;
                dp->sectors = (sectors == 0) ? 63 : sectors;
                dp->rot_rate = (rpm == 0) ? 3600 : rpm;
        }

        dp->cyls = (cyls == 0) ? dp->disksize / (dp->heads * dp->sectors) :
            cyls;

        if (dp->cyls == 0) {
                dp->heads = dp->cyls = 1;
                dp->sectors = dp->disksize;
        }

The development of a useful/careful calculation/validation is left as an 
exercise for the reader.

.... Ken

Reply via email to