This source file includes following definitions.
- spec_open_clone
- spec_close_clone
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <sys/param.h>
21 #include <sys/vnode.h>
22 #include <sys/malloc.h>
23 #include <sys/conf.h>
24 #include <sys/stat.h>
25
26 #include <miscfs/specfs/specdev.h>
27
28 int
29 spec_open_clone(struct vop_open_args *ap)
30 {
31 struct vnode *cvp, *vp = ap->a_vp;
32 struct cloneinfo *cip;
33 int error, i;
34
35 for (i = 1; i < sizeof(vp->v_specbitmap) * NBBY; i++)
36 if (isclr(vp->v_specbitmap, i)) {
37 setbit(vp->v_specbitmap, i);
38 break;
39 }
40
41 if (i == sizeof(vp->v_specbitmap) * NBBY)
42 return (EBUSY);
43
44 printf("spec_open_clone(): cloning device (%d, %d) for pid %u\n",
45 major(vp->v_rdev), minor(vp->v_rdev), curproc->p_pid);
46
47 error = cdevvp(makedev(major(vp->v_rdev), i), &cvp);
48 if (error)
49 return (error);
50
51 VOP_UNLOCK(vp, 0, ap->a_p);
52
53 error = cdevsw[major(vp->v_rdev)].d_open(cvp->v_rdev, ap->a_mode,
54 S_IFCHR, ap->a_p);
55
56 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, ap->a_p);
57
58 if (error) {
59 clrbit(vp->v_specbitmap, i);
60 return (error);
61 }
62
63 cip = malloc(sizeof(struct cloneinfo), M_TEMP, M_WAITOK);
64 cip->ci_data = vp->v_data;
65 cip->ci_vp = cvp;
66
67 cvp->v_specparent = vp;
68 vp->v_flag |= VCLONED;
69 vp->v_data = cip;
70
71 printf("spec_open_clone(): new minor for cloned device is %d\n",
72 minor(cvp->v_rdev));
73
74 return (0);
75 }
76
77 int
78 spec_close_clone(struct vop_close_args *ap)
79 {
80 struct vnode *pvp, *vp = ap->a_vp;
81 int error;
82
83 error = cdevsw[major(vp->v_rdev)].d_close(vp->v_rdev, ap->a_fflag,
84 S_IFCHR, ap->a_p);
85 if (error)
86 return (error);
87
88 pvp = vp->v_specparent;
89 clrbit(pvp->v_specbitmap, minor(vp->v_rdev));
90
91 printf("spec_close_clone(): freeing minor %d of dev %d for"
92 " pid %u\n", minor(vp->v_rdev), major(vp->v_rdev), curproc->p_pid);
93
94 return (0);
95 }