All device access should go through the VOP_ interfaces and not directly through the cdev/bdev interfaces, because access via VOPs provides us with gating. This help us to safely support revoke() and device/driver detach. Since that's the case, you could replicate the cdev_open / bdev_open code in specfs, on the basis that cdev_open/bdev_open are going to die some day. If done that way you would not need a new error code. It may also simplify the code because you can lock device_lock while holding module_lock (defined order is (module_lock -> nearly all other locks), but calling into bdev_open or cdev_open with module_lock held is unsafe; the open entry point may try to load modules.
Attachment:
specfs.diff
Description: Binary data