Subject: Re: 32 bit dev_t, Revision 2
To: Todd Vierling <tv@NetBSD.ORG>
From: Perry E. Metzger <perry@piermont.com>
List: tech-kern
Date: 01/11/1998 16:09:25
Todd Vierling writes:
> 1. dev_t--only when _KERNEL is defined--becomes an opaque type of the
> definition:
>     typedef union { u_int32_t i; } dev_t;
[...]
> AFAIK, this doesn't break userland structure offsets/alignment on any
> existing port.

As CGD has explained, we've had severe problems on things like the ARM
port with this sort of thing, caused by structure alignments being
different from non-structure alignments. You really want to be very
careful about it. I suggest that this might be reasonable as a device
for FINDING all the problems during your initial conversion of the
kernel, but that the committed code should use a uint32.

> 2. After a reasonable "transition period" (one release?  until 2.0?) the
> definition of dev_t will again be reduced to an integer value, and the
> macro API will be reduced to integer definitions.

As I said, this could change the alignment on some ports like the
ARM. You really, really, really want to be careful about this before
doing it.

> 3. Our new dev_t will be split 12 bits major, 20 bits minor.  If the top 12
> bits are zeroes, the dev_t is an "old" device when considering conversion in
> the kernel.

Sounds reasonable, though where did you pick 12 and 20 from?

> These three blocks will have separate bdevsw/cdevsw structures (planned to
> be merged into a devsw structure if the API for the device calls is
> rethought to include character and block distinctions in the calls).
> 
> %0xxxxxxx xxxx:  If the top bit of the major number is 0 (major 0 through
> 4095), the device is a dynamically allocated device (planned for future
> expansion in a dynamic device system and/or LKMs). 

That seems like a ridiculously large space. 4096 major devices is NOT
that large a space, and no real machine is going to dynamically load
2048 device drivers -- devoting half the space to them seems like a
bad idea. Also, I see no reason at all for this coding mechanism. I
mean, sure, it reminds you of class A, B, & C IP addresses, but who
needs it?

> 5. Character and block device major numbers for a given device must match.
> If a character device or a block device does not have a corresponding
> counterpart, the counterpart will be unconfigured.
> 
> 6. When COMPAT_[09-13] is defined in the kernel, the macro major() will
> include inlined support for an old-to-new major number conversion table (one
> for block, and one for character).  Both the major() and minor() macros will
> retrieve only the proper set of bits from the dev_t depending on the top 12
> bits.

Could you explain what kernel ABIs you are preserving by this
mechanism? stat() already does 32 bit dev_t's, so there is no real
userland impact to what you are doing (no userland stuff interprets
dev_t numbers except for stuff like MAKEDEV which doesn't count).

We want to be able to boot a new kernel on a machine with an old /dev,
but I don't see what else here is critical.

> 7. The stat interface will be bumped a version number again, introducing
> __stat14(), __fstat14(), and __lstat14().  These will return a file's dev_t
> unchanged, or if COMPAT_[09-13] are defined, dev_t's always converted to new
> format using the old-to-new conversion table above.  mknod(2) will not be
> changed, and will always create device nodes with the numbers unchanged.

Huh? stat() already has 32 bit dev_t's. I see no reason for doing this
at all.

> 8. The old stat interfaces, if included by a COMPAT_[09-13] option, will do
> direct searchs of the old-to-new table above to demote new dev_t's to 16 bit
> dev_t's.

Why bother with this?

> 14. mknod(8) will be introduced to a new command line option to create "old" 
> style device nodes.

Why?

Perry