Subject: Re: Of SCSI disks and things amiss
To: None <tech-kern@NetBSD.ORG>
From: Waldi Ravens <waldi@moacs.indiv.nl.net>
List: tech-kern
Date: 02/29/1996 22:12:06
> sectors/cylinder: 1188
> cylinders: 3511
> 
> 4 partitions:
> #        size   offset    fstype   [fsize bsize   cpg]
>   d:  4194058        0    unused        0     0         # (Cyl.    0 - 3530*)
> 
> You will note that 1188 * 3511 is 4171068, just a tad below the
> 4194058 sectors used for the size of the raw partition.  If you
> attempt to write this disklabel, you get the complaint:
> 
> 	disklabel: partition d: partition extends past end of unit
> 
> because disklabel computes a d_secperunit of 4171068.  This situation
> is clearly not correct.
> 
> The problem appears to stem from scsi/sd.c, which has:
> 
> 	lp->d_secperunit = sd->params.disksize;
> 	[...]
> 	lp->d_partitions[RAW_PART].p_size =
> 	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);

The last assignment is wrong (also in cd.c and others). At least
newfs(8), newlfs(8) and disklabel(8) expect the size of a partition
in number of sectors, *not* number of DEV_BSIZE units. Therefore
it should read:

	lp->d_partitions[RAW_PART].psize = lp->d_secperunit;

> Evidently, sd->params.disksize includes the reserved sectors on the
> disk.

No, sd->params.disksize is the real medium size, as reported by
the hardware (e.g. SCSI controller).

> Every other piece of code in the kernel appears to calculate
> d_secperunit using d_secpercyl * d_ncylinders.  If no one objects in
> the next few days, I am going to change the first line I quoted from
> scsi/sd.c to:
> 
> 	lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders;

I object. This means that part of the medium will remain unused.
Instead, you should increase the number of cylinders in the disk
pack label to keep disklabel(8) happy:

sectors/cylinder: 256
cylinders: 16470

16 partitions:
#        size   offset    fstype   [fsize bsize   cpg]
  c:  4216172        0    unused        0     0       	# (Cyl.    0 - 16469*)


Regards,
Waldi