Subject: Re: mounting non-BSD partitions.
To: Curt Sampson <cjs@portal.ca>
From: John F. Woods <jfw@jfwhome.funhouse.com>
List: current-users
Date: 06/21/1997 13:23:52
> > As someone pointed out, device numbers are
> > currently 16 bits, but they're stored in a 32 bit field.[1]  If the size of
> > a device number is an attribute of a filesystem, then you could simply have
> > a per-filesystem flag telling whether to unpack the device number as 16 or
> > 32 bits.

> I don't beleive we're talking about the same problem. If we move
> to 16 partitions per disklabel, the obvious numbering scheme would
> have minor nos. 0-15 for sd0, 16-32 for sd1, etc.,

We are talking about the same problem, I'm just doing it poorly ;-).
As I said in a subsequent correction (which didn't go to port-i386
because I fat-fingered the To: line), the person who pointed out the
above also said that it would be desiragle to make the 16->32bit
change at the same time as expanding the partition table.  So, if you
have a backward compatability hack for one case, you can use the same
hack for the other case, too.

It occurs to me, though, that having the device driver check which
filesystem an inode is from to determine how to interpret the device
number is pretty ugly.  However, just about any backward compatability
hack is going to be ugly, so maybe this isn't a problem.  (You don't
really want the inode-fetch routine to muck with the device number on
behalf of drivers, since different drivers will have different partitioning
schemes, most of which would be unaffected by the 8->16 disk partition
expansion.)

It also occurred to me that NFS-mounted partitions can have device
nodes on them (doh!), and NFS will not export some mysterious flag
from the FFS superblock telling you how to interpret device numbers.
That would argue for the 31-bit number scheme, I think.

In fact, the filesystem-flag model has a fatal flaw:  when the kernel
wants to write inodes out to disk, it would need to pack internally-stored
32 bit numbers back into 16 bits, and it has no clue how to adjust the
partitions.  Definitely the 31 bit number scheme is the way to go.

So, the DISKUNIT et al macros could change to something like

/*
 * Translate between device numbers and major/disk unit/disk partition.
 */
#define	DISKUNIT(dev)	(newdev(dev) ? minor(dev) / OLDMAXPARTITIONS : minor(dev) / MAXPARTITIONS)
#define	DISKPART(dev)	(newdev(dev) ? minor(dev) % OLDMAXPARTITIONS : minor(dev) % MAXPARTITIONS)
#define	MAKEDISKDEV(maj, unit, part) \
    (makedev((maj), ((unit) * MAXPARTITIONS) + (part)))

(minor(dev) becomes (dev&0xFFFF), major(dev) becomes ((dev >> 16)&0x7FFF),
and newdev(dev) would be (dev&0x80000000).  Unless you want to split major
and minor differently; 7 bits and 24 bits might not be unreasonable, and
would make for extremely flexible minor device assignments...)

Some annoying problems:  makedev isn't given any clue whether it should
synthesize a 16-bit device number or a 32-bit device number, and drivers
can't tell whether to multiply by MAXPARTITIONS or OLDMAXPARTITIONS.
For those ports with MAXPARTITIONS already equal to 16, this should be
optimized (maybe make it dependant on a definition of OLDMAXPARTITIONS).

Oh well.  Maybe backward compatability isn't worth the pain here.  *I* always
keep a backup root partition handy, doesn't everyone?  ;-)