2 .\" Copyright (c) 2010 Lawrence Stewart <lstewart@FreeBSD.org>
3 .\" All rights reserved.
5 .\" Redistribution and use in source and binary forms, with or without
6 .\" modification, are permitted provided that the following conditions
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.
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
37 .Nm osd_set_reserved ,
38 .Nm osd_free_reserved ,
43 .Nd Object Specific Data
47 .Fn "\*(lp*osd_destructor_t\*(rp" "void *value"
49 .Fn "\*(lp*osd_method_t\*(rp" "void *obj" "void *data"
53 .Fa "osd_destructor_t destructor"
54 .Fa "osd_method_t *methods"
106 .Fa "struct osd *osd"
111 framework provides a mechanism to dynamically associate arbitrary data at
112 run-time with any kernel data structure which has been suitably modified for use
115 The one-off modification required involves embedding a
117 inside the kernel data structure.
119 An additional benefit is that after the initial change to a structure is made,
120 all subsequent use of
122 with the structure involves no changes to the structure's layout.
123 By extension, if the data structure is part of the ABI,
125 provides a way of extending the structure in an ABI preserving manner.
127 The details of the embedded
129 are not relevant to consumers of the
131 framework and should not be manipulated directly.
133 Data associated with a structure is referenced by the
135 framework using a type/slot identifier pair.
136 Types are statically defined in
138 and provide a high-level grouping for slots to be registered under.
139 Slot identifiers are dynamically assigned by the framework when a data type is
142 and remains valid until a corresponding call to
147 function registers a type/slot identifier pair with the
149 framework for use with a new data type.
150 The function may sleep and therefore cannot be called from a non-sleepable
154 argument specifies which high-level type grouping from
156 the slot identifier should be allocated under.
159 argument specifies an optional osd_destructor_t function pointer that will be
160 called for objects of the type being registered which are later destroyed by the
163 NULL may be passed if no destructor is required.
166 argument specifies an optional array of osd_method_t function pointers which
167 can be later invoked by the
170 NULL may be passed if no methods are required.
173 argument is currently only useful with the OSD_JAIL type identifier.
177 function deregisters a previously registered type/slot identifier pair.
178 The function may sleep and therefore cannot be called from a non-sleepable
182 argument specifies which high-level type grouping from
184 the slot identifier is allocated under.
187 argument specifies the slot identifier which is being deregistered and should be
188 the value that was returned by
190 when the data type was registered.
194 function associates a data object pointer with a kernel data structure's
199 argument specifies which high-level type grouping from
201 the slot identifier is allocated under.
204 argument is a pointer to the kernel data structure's
208 pointer associated with it.
211 argument specifies the slot identifier to assign the
216 argument points to a data object to associate with
221 function does the same as
223 but with an extra argument
225 that is internal-use memory previously allocated via
230 function returns the data pointer associated with a kernel data structure's
232 member from the specified type/slot identifier pair.
235 argument specifies which high-level type grouping from
237 the slot identifier is allocated under.
240 argument is a pointer to the kernel data structure's
242 to retrieve the data pointer from.
245 argument specifies the slot identifier to retrieve the data pointer from.
249 function removes the data pointer associated with a kernel data structure's
251 member from the specified type/slot identifier pair.
254 argument specifies which high-level type grouping from
256 the slot identifier is allocated under.
259 argument is a pointer to the kernel data structure's
261 to remove the data pointer from.
264 argument specifies the slot identifier to remove the data pointer from.
265 If an osd_destructor_t function pointer was specified at registration time, the
266 destructor function will be called and passed the data pointer for the type/slot
267 identifier pair which is being deleted.
271 function calls the specified osd_method_t function pointer for all
272 currently registered slots of a given type on the specified
277 The function may sleep and therefore cannot be called from a non-sleepable
281 argument specifies which high-level type grouping from
283 to call the method for.
286 argument specifies the index into the osd_method_t array that was passed to
292 arguments are passed to the method function pointer of each slot.
296 function removes all data object pointers from all currently registered slots
297 for a given type for the specified kernel data structure's
302 argument specifies which high-level type grouping from
304 to remove data pointers from.
307 argument is a pointer to the kernel data structure's
309 to remove all data object pointers for all currently registered slots from.
310 .Sh IMPLEMENTATION NOTES
312 uses a two dimensional matrix (array of arrays) as the data structure to manage
313 the external data associated with a kernel data structure's
316 The type identifier is used as the index into the outer array, and the slot
317 identifier is used as the index into the inner array.
318 To set or retrieve a data pointer for a given type/slot identifier pair,
322 perform the equivalent of array[type][slot], which is both constant time and
329 for the first time, the array for storing data pointers is dynamically allocated
332 with M_NOWAIT to a size appropriate for the slot identifier being set.
333 If a subsequent call to
335 attempts to set a slot identifier which is numerically larger than the slot used
340 is used to grow the array to the appropriate size such that the slot identifier
342 To maximise the efficiency of any code which calls
344 sequentially on a number of different slot identifiers (e.g., during an
345 initialisation phase) one should loop through the slot identifiers in descending
346 order from highest to lowest.
347 This will result in only a single
349 call to create an array of the largest slot size and all subsequent calls to
351 will proceed without any
357 to fail to allocate this array.
358 To ensure that such allocation succeeds,
360 may be called (in a non-blocking context), and it will pre-allocate the
364 Then this pre-allocated memory is passed to
365 .Fn osd_set_reserved ,
366 which will use it if necessary or otherwise discard it.
367 The memory may also be explicitly discarded by calling
368 .Fn osd_free_reserved .
369 As this method always allocates memory whether or not it is ultimately needed,
370 it should be used only rarely, such as in the unlikely event that
376 API is geared towards slot identifiers storing pointers to the same underlying
377 data structure type for a given
380 This is not a requirement, and
382 for example stores completely different data types in slots under the OSD_KHELP
386 internally uses a mix of
391 locks to protect its internal data structures and state.
393 Responsibility for synchronising access to a kernel data structure's
395 member is left to the subsystem that uses the data structure and calls the
402 in read mode, therefore making it safe to use in the majority of contexts within
403 the kernel including most fast paths.
406 returns the slot identifier for the newly registered data type.
411 return zero on success or ENOMEM if the specified type/slot identifier pair
412 triggered an internal
417 will always succeed when
422 returns the data pointer for the specified type/slot identifier pair, or NULL if
423 the slot has not been initialised yet.
426 returns a pointer suitable for passing to
429 .Fn osd_free_reserved .
432 returns zero if no method is run or the method for each slot runs successfully.
433 If a method for a slot returns non-zero,
435 terminates prematurely and returns the method's error to the caller.
440 Object Specific Data (OSD) facility first appeared in
446 facility was written by
447 .An Pawel Jakub Dawidek Aq Mt pjd@FreeBSD.org .
449 This manual page was written by
450 .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org .