xref: /freebsd/share/man/man9/dev_refthread.9 (revision 61e21613)
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.Dd August 29, 2018
26.Dt DEV_REFTHREAD 9
27.Os
28.Sh NAME
29.Nm dev_refthread ,
30.Nm devvn_refthread ,
31.Nm dev_relthread
32.Nd safely access device methods
33.Sh SYNOPSIS
34.In sys/param.h
35.In sys/conf.h
36.Ft "struct cdevsw *"
37.Fn dev_refthread "struct cdev *dev" "int *ref"
38.Ft "struct cdevsw *"
39.Fn devvn_refthread "struct vnode *vp" "struct cdev **devp" "int *ref"
40.Ft void
41.Fn dev_relthread "struct cdev *dev" "int ref"
42.Sh DESCRIPTION
43The
44.Fn dev_refthread
45(or
46.Fn devvn_refthread )
47and
48.Fn dev_relthread
49routines provide a safe way to access
50.Xr devfs 5
51devices that may be concurrently destroyed by
52.Fn destroy_dev
53(e.g., removable media).
54.Pp
55If successful,
56.Fn dev_refthread
57and
58.Fn devvn_refthread
59acquire a "thread reference" to the associated
60.Vt "struct cdev"
61and return a non-NULL pointer to the cdev's
62.Vt "struct cdevsw"
63method table.
64For the duration of that reference, the cdev's associated private data and
65method table object are valid.
66Destruction of the cdev sleeps until the thread reference is released.
67.Pp
68A reference cannot prevent media removal.
69It is an implementation detail of individual drivers how method calls from
70callers with
71.Fn dev_refthread
72references are handled when the device is
73pending destruction.
74A common behavior for disk devices is to return the
75.Er ENXIO
76status, but that is not required by this KPI.
77.Pp
78The
79.Fn devvn_refthread
80variant of
81.Fn dev_refthread
82extracts the
83.Vt "struct cdev"
84pointer out of the
85.Dv VCHR
86.Xr vnode 9
87automatically before performing the same actions as
88.Fn dev_refthread .
89Additionally, a pointer to the
90.Vt "struct cdev"
91is returned to the caller via
92.Fa "*devp" .
93.Fn devvn_refthread
94correctly handles possible parallel reclamation of the vnode.
95.Pp
96.Fn dev_relthread
97is used to release a reference to a
98.Vt "struct cdev" .
99.Fn dev_relthread
100.Sy must
101only be invoked when the associated invocation of
102.Fn dev_refthread
103or
104.Fn devvn_refthread
105returned a non-NULL
106.Vt "struct cdevsw *" .
107.Sh CONTEXT
108.Vt struct cdev
109objects have two reference counts,
110.Va si_refcount
111and
112.Va si_threadcount .
113The
114.Fn dev_refthread ,
115.Fn devvn_refthread ,
116and
117.Fn dev_relthread
118functions manipulate the
119.Va si_threadcount .
120The
121.Va si_threadcount
122reference guarantees the liveness of the
123.Vt struct cdev
124object.
125The other
126.Va si_refcount
127reference provides only the weaker guarantee that the memory backing the
128.Vt struct cdev
129has not been freed.
130.Sh RETURN VALUES
131If
132.Fn dev_refthread
133or
134.Fn devvn_refthread
135are unsuccessful, they return
136.Dv NULL .
137.Bf Em
138If these routines are unsuccessful, they do not increment the
139.Vt "struct cdev"
140.Va si_threadcount
141and do not initialize the value pointed to by the
142.Fa "*ref"
143parameter in any way.
144.Ef
145.Sh SEE ALSO
146.Xr devfs 5 ,
147.Xr destroy_dev 9
148.Sh CAVEATS
149Do not invoke
150.Fn dev_relthread
151unless the matching refthread routine succeeded!
152