Subject: Re: Block Mail
To: None <,,>
From: Mark Gooderum <>
List: current-users
Date: 08/27/1994 14:51:21
> > This jives with the behavior I've seen.  Disklabel writes the label
> > and reads it, okay, but fsck and newfs barf using the raw device about 
> > 1/2 way through the disk (because block #'s are runs off
> > the end of the disk).
>   If this is on the i386 port, I think this behaviour may be because the
> bounds_check_with_label() routine doesn't take into account the physical
> block size.  At the point that sd.c calls bounds_check_with_label(),
> the partition size is in physical sector units, but the block number
> and size are in DEV_BSIZE units.  The check is not being done correctly.
> [I'm not certain how the disk label would be set up for the i386.  I
> found that the partition size and partition offset had to be in units
> of the device physical sector size in order for newfs to work correctly.]
> Hmmm - an incorrect or inconsistent partition offset could be rather
> dangerous.  It could easily cause newfs to write at the wrong spot on
> the disk.

I played a little more.  My fix makes raw reads and writes work okay, at
least at the beginning of the disk.  I can mix and match block sizes and
it works okay.  It also causes no problems for raw and block access to 
512 byte p/sector drives.

The disklabel stuff still futzes, I've done some browsing through
.../i386/disk_subr.c, that seems to be the source of the disk labeling
problems.  I still haven't completely figured out the code, but there 
is a lot of stuff hard coded to DEV_BSIZE dealing with the DOS partition
table.  I'm willing to concede you have to make a 1024 byte/sec disk Unix
only since DOS and it's partition tables assume 512 byte sectors, but there's
definitely some problems still.

> > I would love to help make this work (I've got a couple of older but very
> > big 1024 block SCSI drives I scrounged that otherwise work).
> >  
> > I've played a bit with having physio() stuff the block value into both
> > b_lblkno and b_blkno.  
>   I don't think will work - the getblk() routine in kern/vfs_bio.c is
> already setting b_lblkno and b_blkno to the specified block.  It might
> work better if physio() ensured that b_lbkno was zeroed.

Hmmm.  I'll have to look at that code path...l_blkno seems to be largely
unreferenced elsewhere (sd.c *never* looked at it).

>   If fsck is still having problems thinking it's going off the end of
> the partition, that problem is probably because bounds_check_with_label()
> doesn't take into account the difference in the units between the
> partition size and the block number + I/O length.

I'll look at that as well...

I still can't newfs with the raw seeks (successfully) to the
last block of the partition (which isn't on the end of the disk, there's
still 32M of swap), but then gets EINVAL on trying to write it.  
I'll have to play around more.  Newfsing with the block device works, but
fsck still bounces.

One other (unrelated?) bit...if I dd from /dev/zero to a raw SCSI disk
device with other than a 512 byte block size, it locks the machine...hard.
I'll try to narrow down the limits of this one using a 512 byte drive so 
someone can look at it or give more pointers.