xref: /freebsd/share/man/man9/dev_refthread.9 (revision 8ddb146abcdf061be9f2c0db7e391697dafad85c)
1.\" Copyright (c) 2018 Conrad Meyer <cem@FreeBSD.org>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\" $FreeBSD$
26.\"
27.Dd August 29, 2018
28.Dt DEV_REFTHREAD 9
29.Os
30.Sh NAME
31.Nm dev_refthread ,
32.Nm devvn_refthread ,
33.Nm dev_relthread
34.Nd safely access device methods
35.Sh SYNOPSIS
36.In sys/param.h
37.In sys/conf.h
38.Ft "struct cdevsw *"
39.Fn dev_refthread "struct cdev *dev" "int *ref"
40.Ft "struct cdevsw *"
41.Fn devvn_refthread "struct vnode *vp" "struct cdev **devp" "int *ref"
42.Ft void
43.Fn dev_relthread "struct cdev *dev" "int ref"
44.Sh DESCRIPTION
45The
46.Fn dev_refthread
47(or
48.Fn devvn_refthread )
49and
50.Fn dev_relthread
51routines provide a safe way to access
52.Xr devfs 5
53devices that may be concurrently destroyed by
54.Fn destroy_dev
55(e.g., removable media).
56.Pp
57If successful,
58.Fn dev_refthread
59and
60.Fn devvn_refthread
61acquire a "thread reference" to the associated
62.Vt "struct cdev"
63and return a non-NULL pointer to the cdev's
64.Vt "struct cdevsw"
65method table.
66For the duration of that reference, the cdev's associated private data and
67method table object are valid.
68Destruction of the cdev sleeps until the thread reference is released.
69.Pp
70A reference cannot prevent media removal.
71It is an implementation detail of individual drivers how method calls from
72callers with
73.Fn dev_refthread
74references are handled when the device is
75pending destruction.
76A common behavior for disk devices is to return the
77.Er ENXIO
78status, but that is not required by this KPI.
79.Pp
80The
81.Fn devvn_refthread
82variant of
83.Fn dev_refthread
84extracts the
85.Vt "struct cdev"
86pointer out of the
87.Dv VCHR
88.Xr vnode 9
89automatically before performing the same actions as
90.Fn dev_refthread .
91Additionally, a pointer to the
92.Vt "struct cdev"
93is returned to the caller via
94.Fa "*devp" .
95.Fn devvn_refthread
96correctly handles possible parallel reclamation of the vnode.
97.Pp
98.Fn dev_relthread
99is used to release a reference to a
100.Vt "struct cdev" .
101.Fn dev_relthread
102.Sy must
103only be invoked when the associated invocation of
104.Fn dev_refthread
105or
106.Fn devvn_refthread
107returned a non-NULL
108.Vt "struct cdevsw *" .
109.Sh CONTEXT
110.Vt struct cdev
111objects have two reference counts,
112.Va si_refcount
113and
114.Va si_threadcount .
115The
116.Fn dev_refthread ,
117.Fn devvn_refthread ,
118and
119.Fn dev_relthread
120functions manipulate the
121.Va si_threadcount .
122The
123.Va si_threadcount
124reference guarantees the liveness of the
125.Vt struct cdev
126object.
127The other
128.Va si_refcount
129reference provides only the weaker guarantee that the memory backing the
130.Vt struct cdev
131has not been freed.
132.Sh RETURN VALUES
133If
134.Fn dev_refthread
135or
136.Fn devvn_refthread
137are unsuccessful, they return
138.Dv NULL .
139.Bf Em
140If these routines are unsuccessful, they do not increment the
141.Vt "struct cdev"
142.Va si_threadcount
143and do not initialize the value pointed to by the
144.Fa "*ref"
145parameter in any way.
146.Ef
147.Sh SEE ALSO
148.Xr devfs 5 ,
149.Xr destroy_dev 9
150.Sh CAVEATS
151Do not invoke
152.Fn dev_relthread
153unless the matching refthread routine succeeded!
154