Subject: Re: specified device does *too* match mounted device, and other
To: None <tech-kern@netbsd.org>
From: Jed Davis <jdev@panix.com>
List: tech-kern
Date: 08/23/2006 22:26:05
Jed Davis <jdev@panix.com> writes:

> I have a system where I'm using the init.root sysctl; "mount -u /"
> from inside the chrooted system fails because the inner /dev/raid2a
> (or whatever) is a different vnode from the outer /dev/raid2a whence
> it was mounted, despite both of them having the same dev_t and type.

And, as I pointed out several months ago in PR#32112 and then entirely
forgot (thanks, Pavel), I have another one with this problem because
of an mfs /dev.

This, I realize, is actually not magical; there are in fact supposed
to be two (or N) separate vnodes.  (The documentation is confusing, so
I stared at the source and put in printf()s and looked around in ddb
until it made sense.)  Now, should ffs_mount allow updating from a
different vnode with the same rdev?  I think it should.

> There are also, and I seem to recall that PRs already exist on this,
> incidents with FSes which happen to contain device nodes being
> considered busy despite no evidence of anything on the FS actually in
> use, and which I've suspected of being due to similar aliased-device
> confusion.

And this I think I've _finally_ figured out: it happens when a block
device is bdevvp()ed before it's ever encountered in the filesystem
(e.g., the root device); when the first real vnode for the device is
created, checkalias will splat it on top of the earlier fake vnode,
causing it to inherit any existing opens.

Which is, um, kind of hideous; but at least I'm not the first person
to feel this way:

----------------------------
revision 1.23
date: 1994/04/18 21:03:14;  author: cgd;  state: Exp;  lines: +1 -1
don't let cons dev vnode get subsumed by a 'real' vnode.  the current
scheme of vnode aliasing just *has* to go.
----------------------------

I'll go update the PR.
-- 
(let ((C call-with-current-continuation)) (apply (lambda (x y) (x y)) (map
((lambda (r) ((C C) (lambda (s) (r (lambda l (apply (s s) l))))))  (lambda
(f) (lambda (l) (if (null? l) C (lambda (k) (display (car l)) ((f (cdr l))
(C k)))))))    '((#\J #\d #\D #\v #\s) (#\e #\space #\a #\i #\newline)))))