device cloning on open

Matthew Dillon dillon at
Wed Apr 4 13:49:53 PDT 2007

:Has there been any changes to device cloning support in DFBSD, specifically
:related to this email:
:I'm porting the kqemu module based on the FreeBSD version of it and it works
:now but there can only be one qemu process using the /dev/kqemu device. I
:guess I can just have a list of association between a process and the
:module/device private data for each open() that's managed in the module.
:It's not optimal but it will work until I figure out the best way to keep
:per open data. 
:In FreeBSD >= 5 the per open data is associated to a clone of the device via
:the si_drv1 field. A clone event handler also needs to be registered to do
:the cloning - it's kind of convoluted. 
:In Linux and NetBSD, if I read the code right, the file pointer is passed in
:to the various ops, read, ioctl, write, etc of the driver. I think this
:makes more sense semantically. In Linux the file* is passed in, while in
:NetBSD the module can decide call falloc and fdclone.
:I'm not sure if I want to / can take on the task of adding the per open
:vnode as suggested by Matt, but I'd be interested in hearing what people
:have to say about this.
:Thanks for all of the great work so far.

    At the moment DragonFly passes the file pointer to the VOP open
    function, allowing the VOP open function to change elements of
    the file pointer (for example, to install a different vnode).  The
    file functions typically are left pointing at the specfs VFS which 
    does the translation between a vnode operation and a device operation.
    The file pointer's fp->f_type field is left indicating a 'vnode' type.

    This means that I/O operations running through specfs run through
    the uncloned vnode at the moment and the actual device is picked
    out of the vnode structure.  The vnode represents the filesystem 
    rendezvous (typically /dev/<blahblah>).  Hence why I originally 
    suggested cloning the vnode in order to support a cloned device.

    There is another way we could clone the device, and that would be
    to NOT retain the vnode type in the file pointer but instead to
    create a wholely new file type and wholely new f_ops operations
    set for the file pointer, then point f_data at a cloning structure
    of some sort:

    struct dev_data {
	cdev_t *dd_dev;			/* possibly cloned device */
	struct vnode *dd_orig_vp;	/* original uncloned vnode */

    fp->f_ops = &dev_ops;
    fp->f_type = DTYPE_DEV;
    fp->f_data = (pointer to allocated dev_data structure)

    In otherwords, to create a completely new device abstraction that
    completely bypasses the original vnode and provides storage 
    (dd_dev) for us to clone the device.  No more specfs, no more 
    indirection through the vnode operations vector.  A far more
    direct device access mechanism that happens to also making cloning

    The dd_orig_vp field would remain only to give the new device ops
    the ability to update the vnode's access and modified timestamps
    (if we even care about doing that for cloned entities).


    If you or someone would like to take on this task, I think it would
    be an excellent (and clean) solution to a long standing problem.

					Matthew Dillon 
					<dillon at>

More information about the Kernel mailing list