Subject: Re: dynamic configuration (was Re: PR#4094)
To: None <darrenr@reed.wattle.id.au>
From: Chris Torek <torek@BSDI.COM>
List: tech-kern
Date: 08/25/2000 23:25:17
>Excuse my ignorance for a moment, but if you have a merged devsw entry,
>how do you know which of the character/block devices you get by calling
>open() if you're explicitly after one set of semantics and not the other?

Outside the kernel, in /dev, the file is still a "character" or
"block" special file, and is opened as such.  This gives it a
different kind of vnode with a different set of ops.  (Actually it
just goes through spec_read and spec_write, which switch on vp->v_type
again, which is silly, but never mind all that.)

Inside the kernel, to a first approximation, no driver even cares.
The only thing special about a block-style read is that it happens
directly through xxstrategy() instead of going through rawread()
and physio() first.

For instance, in the current system, when you open the character
device /dev/rsd0a, that calls sdopen(); on the other hand, when
you open the block device /dev/sd0a, that calls sdopen() instead.
"Eh?  How's that again?" :-)  The drivers that do care (such as
disks, when computing "open masks") already use the third argument
to their open and close functions ("ifmt" => S_IFBLK or S_IFCHR)
to tell which is happening:

	int sdopen(dev_t dev, int mode, int ifmt, struct proc *p) {
		...
		/* this actually happens in a function */
		mask = 1 << partition;
		if (ifmt == S_IFBLK)
			x->bopenmask |= mask;
		else
			x->copenmask |= mask;
		x->openmask = x->bopenmask | x->copenmask;
		...
	}

My ultimate goal (when I made this change to BSD/OS, back in the
mid 1990s...) was to remove fluff from the system.  The fastest,
most reliable parts are the ones that are not there.  I did not
get rid of much code (mostly just data, and data tend to be less
buggy than code, in my experience) but it still seemed worthwhile.

Chris