xref: /freebsd/share/man/man9/osd.9 (revision 0b3105a37d7adcadcb720112fed4dc4e8040be99)
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 January 5, 2011
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_get ,
37.Nm osd_del ,
38.Nm osd_call ,
39.Nm osd_exit
40.Nd Object Specific Data
41.Sh SYNOPSIS
42.In sys/osd.h
43.Ft typedef void
44.Fn "\*(lp*osd_destructor_t\*(rp" "void *value"
45.Ft typedef int
46.Fn "\*(lp*osd_method_t\*(rp" "void *obj" "void *data"
47.Ft int
48.Fo osd_register
49.Fa "u_int type"
50.Fa "osd_destructor_t destructor"
51.Fa "osd_method_t *methods"
52.Fc
53.Ft void
54.Fo osd_deregister
55.Fa "u_int type"
56.Fa "u_int slot"
57.Fc
58.Ft int
59.Fo osd_set
60.Fa "u_int type"
61.Fa "struct osd *osd"
62.Fa "u_int slot"
63.Fa "void *value"
64.Fc
65.Ft void *
66.Fo osd_get
67.Fa "u_int type"
68.Fa "struct osd *osd"
69.Fa "u_int slot"
70.Fc
71.Ft void
72.Fo osd_del
73.Fa "u_int type"
74.Fa "struct osd *osd"
75.Fa "u_int slot"
76.Fc
77.Ft int
78.Fo osd_call
79.Fa "u_int type"
80.Fa "u_int method"
81.Fa "void *obj"
82.Fa "void *data"
83.Fc
84.Ft void
85.Fo osd_exit
86.Fa "u_int type"
87.Fa "struct osd *osd"
88.Fc
89.Sh DESCRIPTION
90The
91.Nm
92framework provides a mechanism to dynamically associate arbitrary data at
93run-time with any kernel data structure which has been suitably modified for use
94with
95.Nm .
96The one-off modification required involves embedding a
97.Vt "struct osd"
98inside the kernel data structure.
99.Pp
100An additional benefit is that after the initial change to a structure is made,
101all subsequent use of
102.Nm
103with the structure involves no changes to the structure's layout.
104By extension, if the data structure is part of the ABI,
105.Nm
106provides a way of extending the structure in an ABI preserving manner.
107.Pp
108The details of the embedded
109.Vt "struct osd"
110are not relevant to consumers of the
111.Nm
112framework and should not be manipulated directly.
113.Pp
114Data associated with a structure is referenced by the
115.Nm
116framework using a type/slot identifier pair.
117Types are statically defined in
118.In sys/osd.h
119and provide a high-level grouping for slots to be registered under.
120Slot identifiers are dynamically assigned by the framework when a data type is
121registered using
122.Fn osd_register
123and remains valid until a corresponding call to
124.Fn osd_deregister .
125.Ss Functions
126The
127.Fn osd_register
128function registers a type/slot identifier pair with the
129.Nm
130framework for use with a new data type.
131The function may sleep and therefore cannot be called from a non-sleepable
132context.
133The
134.Fa type
135argument specifies which high-level type grouping from
136.In sys/osd.h
137the slot identifier should be allocated under.
138The
139.Fa destructor
140argument specifies an optional osd_destructor_t function pointer that will be
141called for objects of the type being registered which are later destroyed by the
142.Fn osd_del
143function.
144NULL may be passed if no destructor is required.
145The
146.Fa methods
147argument specifies an optional array of osd_method_t function pointers which
148can be later invoked by the
149.Fn osd_call
150function.
151NULL may be passed if no methods are required.
152The
153.Fa methods
154argument is currently only useful with the OSD_JAIL type identifier.
155.Pp
156The
157.Fn osd_deregister
158function deregisters a previously registered type/slot identifier pair.
159The function may sleep and therefore cannot be called from a non-sleepable
160context.
161The
162.Fa type
163argument specifies which high-level type grouping from
164.In sys/osd.h
165the slot identifier is allocated under.
166The
167.Fa slot
168argument specifies the slot identifier which is being deregistered and should be
169the value that was returned by
170.Fn osd_register
171when the data type was registered.
172.Pp
173The
174.Fn osd_set
175function associates a data object pointer with a kernel data structure's
176.Vt struct osd
177member.
178The
179.Fa type
180argument specifies which high-level type grouping from
181.In sys/osd.h
182the slot identifier is allocated under.
183The
184.Fa osd
185argument is a pointer to the kernel data structure's
186.Vt struct osd
187which will have the
188.Fa value
189pointer associated with it.
190The
191.Fa slot
192argument specifies the slot identifier to assign the
193.Fa value
194pointer to.
195The
196.Fa value
197argument points to a data object to associate with
198.Fa osd .
199.Pp
200The
201.Fn osd_get
202function returns the data pointer associated with a kernel data structure's
203.Vt struct osd
204member from the specified type/slot identifier pair.
205The
206.Fa type
207argument specifies which high-level type grouping from
208.In sys/osd.h
209the slot identifier is allocated under.
210The
211.Fa osd
212argument is a pointer to the kernel data structure's
213.Vt struct osd
214to retrieve the data pointer from.
215The
216.Fa slot
217argument specifies the slot identifier to retrieve the data pointer from.
218.Pp
219The
220.Fn osd_del
221function removes the data pointer associated with a kernel data structure's
222.Vt struct osd
223member from the specified type/slot identifier pair.
224The
225.Fa type
226argument specifies which high-level type grouping from
227.In sys/osd.h
228the slot identifier is allocated under.
229The
230.Fa osd
231argument is a pointer to the kernel data structure's
232.Vt struct osd
233to remove the data pointer from.
234The
235.Fa slot
236argument specifies the slot identifier to remove the data pointer from.
237If an osd_destructor_t function pointer was specified at registration time, the
238destructor function will be called and passed the data pointer for the type/slot
239identifier pair which is being deleted.
240.Pp
241The
242.Fn osd_call
243function calls the specified osd_method_t function pointer for all
244currently registered slots of a given type on the specified
245.Fa obj
246and
247.Fa data
248pointers.
249The function may sleep and therefore cannot be called from a non-sleepable
250context.
251The
252.Fa type
253argument specifies which high-level type grouping from
254.In sys/osd.h
255to call the method for.
256The
257.Fa method
258argument specifies the index into the osd_method_t array that was passed to
259.Fn osd_register .
260The
261.Fa obj
262and
263.Fa data
264arguments are passed to the method function pointer of each slot.
265.Pp
266The
267.Fn osd_exit
268function removes all data object pointers from all currently registered slots
269for a given type for the specified kernel data structure's
270.Vt struct osd
271member.
272The
273.Fa type
274argument specifies which high-level type grouping from
275.In sys/osd.h
276to remove data pointers from.
277The
278.Fa osd
279argument is a pointer to the kernel data structure's
280.Vt struct osd
281to remove all data object pointers for all currently registered slots from.
282.Sh IMPLEMENTATION NOTES
283.Nm
284uses a two dimensional matrix (array of arrays) as the data structure to manage
285the external data associated with a kernel data structure's
286.Vt struct osd
287member.
288The type identifier is used as the index into the outer array, and the slot
289identifier is used as the index into the inner array. To set or retrieve a data
290pointer for a given type/slot identifier pair,
291.Fn osd_set
292and
293.Fn osd_get
294perform the equivalent of array[type][slot], which is both constant time and
295fast.
296.Pp
297If
298.Fn osd_set
299is called on a
300.Vt struct osd
301for the first time, the array for storing data pointers is dynamically allocated
302using
303.Xr malloc 9
304with M_NOWAIT to a size appropriate for the slot identifier being set.
305If a subsequent call to
306.Fn osd_set
307attempts to set a slot identifier which is numerically larger than the slot used
308in the previous
309.Fn osd_set
310call,
311.Xr realloc 9
312is used to grow the array to the appropriate size such that the slot identifier
313can be used.
314To maximise the efficiency of any code which calls
315.Fn osd_set
316sequentially on a number of different slot identifiers (e.g. during an
317initialisation phase) one should loop through the slot identifiers in descending
318order from highest to lowest.
319This will result in only a single
320.Xr malloc 9
321call to create an array of the largest slot size and all subsequent calls to
322.Fn osd_set
323will proceed without any
324.Xr realloc 9
325calls.
326.Pp
327The
328.Nm
329API is geared towards slot identifiers storing pointers to the same underlying
330data structure type for a given
331.Nm
332type identifier.
333This is not a requirement, and
334.Xr khelp 9
335for example stores completely different data types in slots under the OSD_KHELP
336type identifier.
337.Ss Locking
338.Nm
339internally uses a mix of
340.Xr mutex 9 ,
341.Xr rmlock 9
342and
343.Xr sx 9
344locks to protect its internal data structures and state.
345.Pp
346Responsibility for synchronising access to a kernel data structure's
347.Vt struct osd
348member is left to the subsystem that uses the data structure and calls the
349.Nm
350API.
351.Pp
352.Fn osd_get
353only acquires an
354.Xr rmlock
355in read mode, therefore making it safe to use in the majority of contexts within
356the kernel including most fast paths.
357.Sh RETURN VALUES
358.Fn osd_register
359returns the slot identifier for the newly registered data type.
360.Pp
361.Fn osd_set
362returns zero on success or ENOMEM if the specified type/slot identifier pair
363triggered an internal
364.Xr realloc 9
365which failed.
366.Pp
367.Fn osd_get
368returns the data pointer for the specified type/slot identifier pair, or NULL if
369the slot has not been initialised yet.
370.Pp
371.Fn osd_call
372returns zero if no method is run or the method for each slot runs successfully.
373If a method for a slot returns non-zero,
374.Fn osd_call
375terminates prematurely and returns the method's error to the caller.
376.Sh SEE ALSO
377.Xr khelp 9
378.Sh HISTORY
379The
380Object Specific Data (OSD) facility first appeared in
381.Fx 8.0 .
382.Sh AUTHORS
383.An -nosplit
384The
385.Nm
386facility was written by
387.An Pawel Jakub Dawidek Aq Mt pjd@FreeBSD.org .
388.Pp
389This manual page was written by
390.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org .
391