Subject: Supporting sector size != DEV_BSIZE
To: Chuck Silvers <chuq@chuq.com>
From: Trevin Beattie <trevin@xmission.com>
List: tech-kern
Date: 05/31/2002 11:27:45
I should have paid more attention to what you already suggested, Chuck! :^)

I was looking through the bounds_check_with_label function
(arch/i386/i386/disksubr.c, which, BTW, is not called for partition 'd'),
and almost right away noticed a bad inconsistency.  The function starts by
converting bytes to sectors:

481:	sz = howmany(bp->b_bcount, lp->d_secsize);

It then adds the sector count to the _block number_ and checks the result
against the partition size:

483:	if (bp->b_blkno + sz > p->p_size) {
484:		sz = p->p_size - bp->b_blkno;

If the request runs past the end of the partition, it truncates the size
and converts the number of *DEV_BSIZE blocks* to bytes:

496:		bp->b_bcount = sz << DEV_BSHIFT;

Obviously, one or more of the above lines is incorrect and must be changed,
because line 496 is inconsistent with line 481.  But I have no idea what
the correct change should be, because I can't find any formal definition
for the units used by b_blkno.  <sys/buf.h> defines this parameter as the
"underlying physical block number"; but is that a physical sector or a
DEV_BSIZE block?

My guess, judging from dev/vnd.c:376, is that b_blkno is in DEV_BSIZE
units.  But the value of p_size (partition size) stored on the disk label
of my virtual disk is in units of sectors.  This would seem to indicate
that b_blkno needs shifting everywhere it's used in
bounds_check_with_label.  Unless the partition data should actually be in
terms of DEV_BSIZE instead of sectors, in which case disklabel needs to be
changed.

Can anybody refer me to the design specs for the file system?

-- Trevin

>Date: Thu, 30 May 2002 15:37:32 -0700
>To: Chuck Silvers <chuq@chuq.com>
>From: Trevin Beattie <trevin@xmission.com>
>Subject: Re: Supporting sector size != DEV_BSIZE
>
>OK - I've downloaded NetBSD-current for May 25 and compiled a new kernel
(also had to install the base and comp sets from the 1.5ZC snapshot in
order to compile the kernel).  Before making any modifications, I tried
creating a 2048-B/s virtual disk and dumping the *vnd0d device to see where
things currently stand.
>
>I am impressed!  Both the block and character device interfaces appear to
be reading the virtual disk correctly, without any gaps or repeats, and
having the correct number of bytes.  The only glitch was that dd gave an
I/O error at the end of the virtual disk.  I don't know whether that's
because it had the wrong sector count or it just didn't know / ignored the
device size?  Anyway, it looked very promising.
>
>Next I tried creating a 4.2BSD filesystem on the virtual disk.  disklabel
worked perfectly.  In newfs, however, I encountered a real problem:
>
>	wtfs: write error for sector 511: Invalid argument
>
>(from mkfs.c:1147).  At first I thought maybe newfs was trying to write
512 bytes instead of using the sector size, but when I traced the code, I
saw that the size passed to write is in fact 2048, which should be correct.
>
>Next I tried *writing* the virtual disk using dd, and after playing around
I discovered where the problem was.  For some reason, reads and writes to
the vnd0d partition work correctly, but the vnd0c and vnd0a partitions can
only access 1/4 of the total sectors!  The first quarter of the disk is
read correctly, AFAIK, so the problem is just that something is munging the
total block count somewhere.
>
>What's even more interesting is that I tried changing the 'a' partition to
the first quarter of the virtual disk, yet dd still failed with an I/O
error after 1/4 of the _new_ partition size (1/16 of the total disk)!  So
the munging, it seems, is done on the partition size, not the disk size.
>
>Do you have any advice on where to start looking when I start digging into
the kernel code?
>
>-- Trevin
>
>P.S.: Should this be submitted as a new PR?
>
>At 06:24 PM 5/28/2002 -0700, you wrote:
>>hi,
>>
>>nope, I got distracted by other stuff and never got back to this.
>>
>>as I recall, there were just a couple places that needed to be changed
>>to be able to mount an FFS file system that lived in a 1k-sector disk.
>>it was bounds_check_with_label() and the FFS mount code (I think).
>>bounds_check_with_label() is different on each $MACHINE, the other
>>bit is common code.  there may be other minor bits but those were enough
>>to do basic file system stuff.
>>
>>-Chuck
>
-----------------------
Trevin Beattie          "Do not meddle in the affairs of wizards,
trevin@xmission.com     for you are crunchy and good with ketchup."
      {:->                                     --unknown