Subject: Re: Understanding foo_open, foo_read, etc.
To: None <>
From: Peter Seebach <>
List: tech-kern
Date: 08/29/2006 17:26:30
In message <200608292158.RAA14371@Sparkle.Rodents.Montreal.QC.CA>, der Mouse wr
>I think part of the problem here is the distinction between a special
>device file and a non-vnode file descriptor.

Yes.  I think that's exactly it.

>This question almost doesn't make sense; it's a conceptual type clash,
>a bit like asking under what circumstances would one speak "without"
>instead of "English".  You have to use a fileops when filling in a
>struct file *; you have to use a cdevsw when setting up a device
>special vnode.  (I'm ignoring, for purposes of this email, the
>distinction between a block device (bdevsw) and a character device
>(cdevsw); it's largely a historical artifact and would only confuse an
>already confusing thing further.  I can go into it if you want.)

No problem, I get that part.

What mystifies me is that the cdevsw open routine on NetBSD fills in
a struct file *, then "returns" it using fdclone (which actually does
deep magic elsewhere in the kernel to drop the cdevsw-based file entry
it had already created, and take the new one instead), and the FreeBSD
one just returns zero, letting the cdevsw structure do the work...

Because the FreeBSD code is cloning the device, and the NetBSD code isn't.

>As for why they do do this, I can only speculate.  My guess is that
>it's a way to do something like cloning devices, but in a less
>OS-dependent way than actually using the OS's cloning device support.

Probably; or, rather, it's a good way to implement the functionality on
NetBSD without relying on FreeBSD's specific way of cloning devices.

>I hope this as been more illuminating than obscuring.  It's a bit
>complicated, but then, it's a complicated subject.  I'll be happy to go
>into more detail if you want, or take correction if I've botched
>something in this description.

I think I now understand it.  The obvious thing I was missing was the
filling in of a struct file in generic code that uses the vnode operations,
and the subtle thing I was missing was the special case where a return
of EMOVEFD deletes the generic struct file and puts in a new one that you
created out of band.