xref: /freebsd/share/man/man9/osd.9 (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1.\"
2.\" Copyright (c) 2010 Lawrence Stewart <lstewart@FreeBSD.org>
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\"    notice, this list of conditions, and the following disclaimer,
10.\"    without modification, immediately at the beginning of the file.
11.\" 2. The name of the author may not be used to endorse or promote products
12.\"    derived from this software without specific prior written permission.
13.\"
14.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
18.\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24.\" SUCH DAMAGE.
25.\"
26.\" $FreeBSD$
27.\"
28.Dd April 26, 2016
29.Dt OSD 9
30.Os
31.Sh NAME
32.Nm osd ,
33.Nm osd_register ,
34.Nm osd_deregister ,
35.Nm osd_set ,
36.Nm osd_reserve ,
37.Nm osd_set_reserved ,
38.Nm osd_free_reserved ,
39.Nm osd_get ,
40.Nm osd_del ,
41.Nm osd_call ,
42.Nm osd_exit
43.Nd Object Specific Data
44.Sh SYNOPSIS
45.In sys/osd.h
46.Ft typedef void
47.Fn "\*(lp*osd_destructor_t\*(rp" "void *value"
48.Ft typedef int
49.Fn "\*(lp*osd_method_t\*(rp" "void *obj" "void *data"
50.Ft int
51.Fo osd_register
52.Fa "u_int type"
53.Fa "osd_destructor_t destructor"
54.Fa "osd_method_t *methods"
55.Fc
56.Ft void
57.Fo osd_deregister
58.Fa "u_int type"
59.Fa "u_int slot"
60.Fc
61.Ft int
62.Fo osd_set
63.Fa "u_int type"
64.Fa "struct osd *osd"
65.Fa "u_int slot"
66.Fa "void *value"
67.Fc
68.Ft void **
69.Fo osd_reserve
70.Fa "u_int slot"
71.Fc
72.Ft int
73.Fo osd_set_reserved
74.Fa "u_int type"
75.Fa "struct osd *osd"
76.Fa "u_int slot"
77.Fa "void **rsv"
78.Fa "void *value"
79.Fc
80.Ft void
81.Fo osd_free_reserved
82.Fa "void **rsv"
83.Fc
84.Ft void *
85.Fo osd_get
86.Fa "u_int type"
87.Fa "struct osd *osd"
88.Fa "u_int slot"
89.Fc
90.Ft void
91.Fo osd_del
92.Fa "u_int type"
93.Fa "struct osd *osd"
94.Fa "u_int slot"
95.Fc
96.Ft int
97.Fo osd_call
98.Fa "u_int type"
99.Fa "u_int method"
100.Fa "void *obj"
101.Fa "void *data"
102.Fc
103.Ft void
104.Fo osd_exit
105.Fa "u_int type"
106.Fa "struct osd *osd"
107.Fc
108.Sh DESCRIPTION
109The
110.Nm
111framework provides a mechanism to dynamically associate arbitrary data at
112run-time with any kernel data structure which has been suitably modified for use
113with
114.Nm .
115The one-off modification required involves embedding a
116.Vt "struct osd"
117inside the kernel data structure.
118.Pp
119An additional benefit is that after the initial change to a structure is made,
120all subsequent use of
121.Nm
122with the structure involves no changes to the structure's layout.
123By extension, if the data structure is part of the ABI,
124.Nm
125provides a way of extending the structure in an ABI preserving manner.
126.Pp
127The details of the embedded
128.Vt "struct osd"
129are not relevant to consumers of the
130.Nm
131framework and should not be manipulated directly.
132.Pp
133Data associated with a structure is referenced by the
134.Nm
135framework using a type/slot identifier pair.
136Types are statically defined in
137.In sys/osd.h
138and provide a high-level grouping for slots to be registered under.
139Slot identifiers are dynamically assigned by the framework when a data type is
140registered using
141.Fn osd_register
142and remains valid until a corresponding call to
143.Fn osd_deregister .
144.Ss Functions
145The
146.Fn osd_register
147function registers a type/slot identifier pair with the
148.Nm
149framework for use with a new data type.
150The function may sleep and therefore cannot be called from a non-sleepable
151context.
152The
153.Fa type
154argument specifies which high-level type grouping from
155.In sys/osd.h
156the slot identifier should be allocated under.
157The
158.Fa destructor
159argument specifies an optional osd_destructor_t function pointer that will be
160called for objects of the type being registered which are later destroyed by the
161.Fn osd_del
162function.
163NULL may be passed if no destructor is required.
164The
165.Fa methods
166argument specifies an optional array of osd_method_t function pointers which
167can be later invoked by the
168.Fn osd_call
169function.
170NULL may be passed if no methods are required.
171The
172.Fa methods
173argument is currently only useful with the OSD_JAIL type identifier.
174.Pp
175The
176.Fn osd_deregister
177function deregisters a previously registered type/slot identifier pair.
178The function may sleep and therefore cannot be called from a non-sleepable
179context.
180The
181.Fa type
182argument specifies which high-level type grouping from
183.In sys/osd.h
184the slot identifier is allocated under.
185The
186.Fa slot
187argument specifies the slot identifier which is being deregistered and should be
188the value that was returned by
189.Fn osd_register
190when the data type was registered.
191.Pp
192The
193.Fn osd_set
194function associates a data object pointer with a kernel data structure's
195.Vt struct osd
196member.
197The
198.Fa type
199argument specifies which high-level type grouping from
200.In sys/osd.h
201the slot identifier is allocated under.
202The
203.Fa osd
204argument is a pointer to the kernel data structure's
205.Vt struct osd
206which will have the
207.Fa value
208pointer associated with it.
209The
210.Fa slot
211argument specifies the slot identifier to assign the
212.Fa value
213pointer to.
214The
215.Fa value
216argument points to a data object to associate with
217.Fa osd .
218.Pp
219The
220.Fn osd_set_reserved
221function does the same as
222.Fn osd_set ,
223but with an extra argument
224.Fa rsv
225that is internal-use memory previously allocated via
226.Fn osd_reserve .
227.Pp
228The
229.Fn osd_get
230function returns the data pointer associated with a kernel data structure's
231.Vt struct osd
232member from the specified type/slot identifier pair.
233The
234.Fa type
235argument specifies which high-level type grouping from
236.In sys/osd.h
237the slot identifier is allocated under.
238The
239.Fa osd
240argument is a pointer to the kernel data structure's
241.Vt struct osd
242to retrieve the data pointer from.
243The
244.Fa slot
245argument specifies the slot identifier to retrieve the data pointer from.
246.Pp
247The
248.Fn osd_del
249function removes the data pointer associated with a kernel data structure's
250.Vt struct osd
251member from the specified type/slot identifier pair.
252The
253.Fa type
254argument specifies which high-level type grouping from
255.In sys/osd.h
256the slot identifier is allocated under.
257The
258.Fa osd
259argument is a pointer to the kernel data structure's
260.Vt struct osd
261to remove the data pointer from.
262The
263.Fa slot
264argument specifies the slot identifier to remove the data pointer from.
265If an osd_destructor_t function pointer was specified at registration time, the
266destructor function will be called and passed the data pointer for the type/slot
267identifier pair which is being deleted.
268.Pp
269The
270.Fn osd_call
271function calls the specified osd_method_t function pointer for all
272currently registered slots of a given type on the specified
273.Fa obj
274and
275.Fa data
276pointers.
277The function may sleep and therefore cannot be called from a non-sleepable
278context.
279The
280.Fa type
281argument specifies which high-level type grouping from
282.In sys/osd.h
283to call the method for.
284The
285.Fa method
286argument specifies the index into the osd_method_t array that was passed to
287.Fn osd_register .
288The
289.Fa obj
290and
291.Fa data
292arguments are passed to the method function pointer of each slot.
293.Pp
294The
295.Fn osd_exit
296function removes all data object pointers from all currently registered slots
297for a given type for the specified kernel data structure's
298.Vt struct osd
299member.
300The
301.Fa type
302argument specifies which high-level type grouping from
303.In sys/osd.h
304to remove data pointers from.
305The
306.Fa osd
307argument is a pointer to the kernel data structure's
308.Vt struct osd
309to remove all data object pointers for all currently registered slots from.
310.Sh IMPLEMENTATION NOTES
311.Nm
312uses a two dimensional matrix (array of arrays) as the data structure to manage
313the external data associated with a kernel data structure's
314.Vt struct osd
315member.
316The type identifier is used as the index into the outer array, and the slot
317identifier is used as the index into the inner array.
318To set or retrieve a data pointer for a given type/slot identifier pair,
319.Fn osd_set
320and
321.Fn osd_get
322perform the equivalent of array[type][slot], which is both constant time and
323fast.
324.Pp
325If
326.Fn osd_set
327is called on a
328.Vt struct osd
329for the first time, the array for storing data pointers is dynamically allocated
330using
331.Xr malloc 9
332with M_NOWAIT to a size appropriate for the slot identifier being set.
333If a subsequent call to
334.Fn osd_set
335attempts to set a slot identifier which is numerically larger than the slot used
336in the previous
337.Fn osd_set
338call,
339.Xr realloc 9
340is used to grow the array to the appropriate size such that the slot identifier
341can be used.
342To maximise the efficiency of any code which calls
343.Fn osd_set
344sequentially on a number of different slot identifiers (e.g., during an
345initialisation phase) one should loop through the slot identifiers in descending
346order from highest to lowest.
347This will result in only a single
348.Xr malloc 9
349call to create an array of the largest slot size and all subsequent calls to
350.Fn osd_set
351will proceed without any
352.Xr realloc 9
353calls.
354.Pp
355It is possible for
356.Fn osd_set
357to fail to allocate this array.
358To ensure that such allocation succeeds,
359.Fn osd_reserve
360may be called (in a non-blocking context), and it will pre-allocate the
361memory via
362.Xr malloc 9
363with M_WAITOK.
364Then this pre-allocated memory is passed to
365.Fn osd_set_reserved ,
366which will use it if necessary or otherwise discard it.
367The memory may also be explicitly discarded by calling
368.Fn osd_free_reserved .
369As this method always allocates memory whether or not it is ultimately needed,
370it should be used only rarely, such as in the unlikely event that
371.Fn osd_set
372fails.
373.Pp
374The
375.Nm
376API is geared towards slot identifiers storing pointers to the same underlying
377data structure type for a given
378.Nm
379type identifier.
380This is not a requirement, and
381.Xr khelp 9
382for example stores completely different data types in slots under the OSD_KHELP
383type identifier.
384.Ss Locking
385.Nm
386internally uses a mix of
387.Xr mutex 9 ,
388.Xr rmlock 9
389and
390.Xr sx 9
391locks to protect its internal data structures and state.
392.Pp
393Responsibility for synchronising access to a kernel data structure's
394.Vt struct osd
395member is left to the subsystem that uses the data structure and calls the
396.Nm
397API.
398.Pp
399.Fn osd_get
400only acquires an
401.Xr rmlock
402in read mode, therefore making it safe to use in the majority of contexts within
403the kernel including most fast paths.
404.Sh RETURN VALUES
405.Fn osd_register
406returns the slot identifier for the newly registered data type.
407.Pp
408.Fn osd_set
409and
410.Fn osd_set_reserved
411return zero on success or ENOMEM if the specified type/slot identifier pair
412triggered an internal
413.Xr realloc 9
414which failed
415.Ns (
416.Fn osd_set_reserved
417will always succeed when
418.Fa rsv
419is non-NULL).
420.Pp
421.Fn osd_get
422returns the data pointer for the specified type/slot identifier pair, or NULL if
423the slot has not been initialised yet.
424.Pp
425.Fn osd_reserve
426returns a pointer suitable for passing to
427.Fn osd_set_reserved
428or
429.Fn osd_free_reserved .
430.Pp
431.Fn osd_call
432returns zero if no method is run or the method for each slot runs successfully.
433If a method for a slot returns non-zero,
434.Fn osd_call
435terminates prematurely and returns the method's error to the caller.
436.Sh SEE ALSO
437.Xr khelp 9
438.Sh HISTORY
439The
440Object Specific Data (OSD) facility first appeared in
441.Fx 8.0 .
442.Sh AUTHORS
443.An -nosplit
444The
445.Nm
446facility was written by
447.An Pawel Jakub Dawidek Aq Mt pjd@FreeBSD.org .
448.Pp
449This manual page was written by
450.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org .
451