summaryrefslogtreecommitdiff
path: root/sys/miscfs/specfs/spec_vnops.c
diff options
context:
space:
mode:
authorThordur I. Bjornsson <thib@cvs.openbsd.org>2008-04-08 14:46:46 +0000
committerThordur I. Bjornsson <thib@cvs.openbsd.org>2008-04-08 14:46:46 +0000
commit3ed10c5914354145edb68af222916b1f269f6dc7 (patch)
tree1501c0d5236e47184b662c2d0d7f6d5868314dd6 /sys/miscfs/specfs/spec_vnops.c
parent34fe724f25d91e8ccb959ccc4dbe829541f8faa7 (diff)
bring cloning up too date; Munge it so it will work with atleast
oga@'s upcoming DRM changes and too some degree ratchov@'s audio work. It still works for bpf's though. Parts from ratchov@; fstat(1) parts from Pedro Martelletto; tested by many, ok'ed by a few; "get going with cloning" deraadt@
Diffstat (limited to 'sys/miscfs/specfs/spec_vnops.c')
-rw-r--r--sys/miscfs/specfs/spec_vnops.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c
index 97bfdf61f85..e5d3f2c86f0 100644
--- a/sys/miscfs/specfs/spec_vnops.c
+++ b/sys/miscfs/specfs/spec_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: spec_vnops.c,v 1.44 2007/12/27 13:59:12 thib Exp $ */
+/* $OpenBSD: spec_vnops.c,v 1.45 2008/04/08 14:46:45 thib Exp $ */
/* $NetBSD: spec_vnops.c,v 1.29 1996/04/22 01:42:38 christos Exp $ */
/*
@@ -529,6 +529,8 @@ spec_close(void *v)
vrele(vp);
ap->a_p->p_session->s_ttyvp = NULL;
}
+ if (cdevsw[major(dev)].d_flags & D_CLONE)
+ return (spec_close_clone(ap));
/*
* If the vnode is locked, then we are in the midst
* of forcably closing the device, otherwise we only
@@ -536,8 +538,6 @@ spec_close(void *v)
*/
if (vcount(vp) > 1 && (vp->v_flag & VXLOCK) == 0)
return (0);
- if (cdevsw[major(dev)].d_flags & D_CLONE)
- return (spec_close_clone(ap));
devclose = cdevsw[major(dev)].d_close;
mode = S_IFCHR;
break;
@@ -579,6 +579,47 @@ spec_close(void *v)
return ((*devclose)(dev, ap->a_fflag, mode, ap->a_p));
}
+int
+spec_getattr(void *v)
+{
+ struct vop_getattr_args *ap = v;
+ struct vnode *vp = ap->a_vp;
+
+ if (!(vp->v_flag & VCLONE))
+ return (EBADF);
+
+ return (VOP_GETATTR(vp->v_specparent, ap->a_vap, ap->a_cred, ap->a_p));
+}
+
+int
+spec_setattr(void *v)
+{
+ struct vop_getattr_args *ap = v;
+ struct vnode *vp = ap->a_vp;
+ int error;
+
+ if (!(vp->v_flag & VCLONE))
+ return (EBADF);
+
+ vn_lock(vp->v_specparent, LK_EXCLUSIVE|LK_RETRY, ap->a_p);
+ error = VOP_SETATTR(vp->v_specparent, ap->a_vap, ap->a_cred, ap->a_p);
+ VOP_UNLOCK(vp, 0, ap->a_p);
+
+ return (error);
+}
+
+int
+spec_access(void *v)
+{
+ struct vop_access_args *ap = v;
+ struct vnode *vp = ap->a_vp;
+
+ if (!(vp->v_flag & VCLONE))
+ return (EBADF);
+
+ return (VOP_ACCESS(vp->v_specparent, ap->a_mode, ap->a_cred, ap->a_p));
+}
+
/*
* Print out the contents of a special device vnode.
*/