Documentation: Converted the `kobject.txt` to rst format
Reviewed and converted the `kobject.txt` format to rst in place. Signed-off-by: Sameer Rahmani <lxsameer@gnu.org> Link: https://lore.kernel.org/r/20200225222125.61874-1-lxsameer@gnu.org Signed-off-by: Jonathan Corbet <corbet@lwn.net>
This commit is contained in:
parent
373e8ffafd
commit
669a5cc8c5
|
@ -25,7 +25,7 @@ some terms we will be working with.
|
|||
usually embedded within some other structure which contains the stuff
|
||||
the code is really interested in.
|
||||
|
||||
No structure should EVER have more than one kobject embedded within it.
|
||||
No structure should **EVER** have more than one kobject embedded within it.
|
||||
If it does, the reference counting for the object is sure to be messed
|
||||
up and incorrect, and your code will be buggy. So do not do this.
|
||||
|
||||
|
@ -55,7 +55,7 @@ a larger, domain-specific object. To this end, kobjects will be found
|
|||
embedded in other structures. If you are used to thinking of things in
|
||||
object-oriented terms, kobjects can be seen as a top-level, abstract class
|
||||
from which other classes are derived. A kobject implements a set of
|
||||
capabilities which are not particularly useful by themselves, but which are
|
||||
capabilities which are not particularly useful by themselves, but are
|
||||
nice to have in other objects. The C language does not allow for the
|
||||
direct expression of inheritance, so other techniques - such as structure
|
||||
embedding - must be used.
|
||||
|
@ -65,12 +65,12 @@ this is analogous as to how "list_head" structs are rarely useful on
|
|||
their own, but are invariably found embedded in the larger objects of
|
||||
interest.)
|
||||
|
||||
So, for example, the UIO code in drivers/uio/uio.c has a structure that
|
||||
So, for example, the UIO code in ``drivers/uio/uio.c`` has a structure that
|
||||
defines the memory region associated with a uio device::
|
||||
|
||||
struct uio_map {
|
||||
struct kobject kobj;
|
||||
struct uio_mem *mem;
|
||||
struct kobject kobj;
|
||||
struct uio_mem *mem;
|
||||
};
|
||||
|
||||
If you have a struct uio_map structure, finding its embedded kobject is
|
||||
|
@ -78,30 +78,30 @@ just a matter of using the kobj member. Code that works with kobjects will
|
|||
often have the opposite problem, however: given a struct kobject pointer,
|
||||
what is the pointer to the containing structure? You must avoid tricks
|
||||
(such as assuming that the kobject is at the beginning of the structure)
|
||||
and, instead, use the container_of() macro, found in <linux/kernel.h>::
|
||||
and, instead, use the container_of() macro, found in ``<linux/kernel.h>``::
|
||||
|
||||
container_of(pointer, type, member)
|
||||
|
||||
where:
|
||||
|
||||
* "pointer" is the pointer to the embedded kobject,
|
||||
* "type" is the type of the containing structure, and
|
||||
* "member" is the name of the structure field to which "pointer" points.
|
||||
* ``pointer`` is the pointer to the embedded kobject,
|
||||
* ``type`` is the type of the containing structure, and
|
||||
* ``member`` is the name of the structure field to which ``pointer`` points.
|
||||
|
||||
The return value from container_of() is a pointer to the corresponding
|
||||
container type. So, for example, a pointer "kp" to a struct kobject
|
||||
embedded *within* a struct uio_map could be converted to a pointer to the
|
||||
*containing* uio_map structure with::
|
||||
container type. So, for example, a pointer ``kp`` to a struct kobject
|
||||
embedded **within** a struct uio_map could be converted to a pointer to the
|
||||
**containing** uio_map structure with::
|
||||
|
||||
struct uio_map *u_map = container_of(kp, struct uio_map, kobj);
|
||||
|
||||
For convenience, programmers often define a simple macro for "back-casting"
|
||||
For convenience, programmers often define a simple macro for **back-casting**
|
||||
kobject pointers to the containing type. Exactly this happens in the
|
||||
earlier drivers/uio/uio.c, as you can see here::
|
||||
earlier ``drivers/uio/uio.c``, as you can see here::
|
||||
|
||||
struct uio_map {
|
||||
struct kobject kobj;
|
||||
struct uio_mem *mem;
|
||||
struct kobject kobj;
|
||||
struct uio_mem *mem;
|
||||
};
|
||||
|
||||
#define to_map(map) container_of(map, struct uio_map, kobj)
|
||||
|
@ -125,7 +125,7 @@ must have an associated kobj_type. After calling kobject_init(), to
|
|||
register the kobject with sysfs, the function kobject_add() must be called::
|
||||
|
||||
int kobject_add(struct kobject *kobj, struct kobject *parent,
|
||||
const char *fmt, ...);
|
||||
const char *fmt, ...);
|
||||
|
||||
This sets up the parent of the kobject and the name for the kobject
|
||||
properly. If the kobject is to be associated with a specific kset,
|
||||
|
@ -172,13 +172,13 @@ call to kobject_uevent()::
|
|||
|
||||
int kobject_uevent(struct kobject *kobj, enum kobject_action action);
|
||||
|
||||
Use the KOBJ_ADD action for when the kobject is first added to the kernel.
|
||||
Use the **KOBJ_ADD** action for when the kobject is first added to the kernel.
|
||||
This should be done only after any attributes or children of the kobject
|
||||
have been initialized properly, as userspace will instantly start to look
|
||||
for them when this call happens.
|
||||
|
||||
When the kobject is removed from the kernel (details on how to do that are
|
||||
below), the uevent for KOBJ_REMOVE will be automatically created by the
|
||||
below), the uevent for **KOBJ_REMOVE** will be automatically created by the
|
||||
kobject core, so the caller does not have to worry about doing that by
|
||||
hand.
|
||||
|
||||
|
@ -238,7 +238,7 @@ Both types of attributes used here, with a kobject that has been created
|
|||
with the kobject_create_and_add(), can be of type kobj_attribute, so no
|
||||
special custom attribute is needed to be created.
|
||||
|
||||
See the example module, samples/kobject/kobject-example.c for an
|
||||
See the example module, ``samples/kobject/kobject-example.c`` for an
|
||||
implementation of a simple kobject and attributes.
|
||||
|
||||
|
||||
|
@ -270,10 +270,10 @@ such a method has a form like::
|
|||
|
||||
void my_object_release(struct kobject *kobj)
|
||||
{
|
||||
struct my_object *mine = container_of(kobj, struct my_object, kobj);
|
||||
struct my_object *mine = container_of(kobj, struct my_object, kobj);
|
||||
|
||||
/* Perform any additional cleanup on this object, then... */
|
||||
kfree(mine);
|
||||
/* Perform any additional cleanup on this object, then... */
|
||||
kfree(mine);
|
||||
}
|
||||
|
||||
One important point cannot be overstated: every kobject must have a
|
||||
|
@ -297,11 +297,11 @@ instead, it is associated with the ktype. So let us introduce struct
|
|||
kobj_type::
|
||||
|
||||
struct kobj_type {
|
||||
void (*release)(struct kobject *kobj);
|
||||
const struct sysfs_ops *sysfs_ops;
|
||||
struct attribute **default_attrs;
|
||||
const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
|
||||
const void *(*namespace)(struct kobject *kobj);
|
||||
void (*release)(struct kobject *kobj);
|
||||
const struct sysfs_ops *sysfs_ops;
|
||||
struct attribute **default_attrs;
|
||||
const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
|
||||
const void *(*namespace)(struct kobject *kobj);
|
||||
};
|
||||
|
||||
This structure is used to describe a particular type of kobject (or, more
|
||||
|
@ -352,8 +352,8 @@ created and never declared statically or on the stack. To create a new
|
|||
kset use::
|
||||
|
||||
struct kset *kset_create_and_add(const char *name,
|
||||
struct kset_uevent_ops *u,
|
||||
struct kobject *parent);
|
||||
struct kset_uevent_ops *u,
|
||||
struct kobject *parent);
|
||||
|
||||
When you are finished with the kset, call::
|
||||
|
||||
|
@ -365,16 +365,16 @@ Because other references to the kset may still exist, the release may happen
|
|||
after kset_unregister() returns.
|
||||
|
||||
An example of using a kset can be seen in the
|
||||
samples/kobject/kset-example.c file in the kernel tree.
|
||||
``samples/kobject/kset-example.c`` file in the kernel tree.
|
||||
|
||||
If a kset wishes to control the uevent operations of the kobjects
|
||||
associated with it, it can use the struct kset_uevent_ops to handle it::
|
||||
|
||||
struct kset_uevent_ops {
|
||||
int (*filter)(struct kset *kset, struct kobject *kobj);
|
||||
const char *(*name)(struct kset *kset, struct kobject *kobj);
|
||||
int (*uevent)(struct kset *kset, struct kobject *kobj,
|
||||
struct kobj_uevent_env *env);
|
||||
int (*filter)(struct kset *kset, struct kobject *kobj);
|
||||
const char *(*name)(struct kset *kset, struct kobject *kobj);
|
||||
int (*uevent)(struct kset *kset, struct kobject *kobj,
|
||||
struct kobj_uevent_env *env);
|
||||
};
|
||||
|
||||
|
||||
|
@ -408,8 +408,8 @@ Kobject removal
|
|||
After a kobject has been registered with the kobject core successfully, it
|
||||
must be cleaned up when the code is finished with it. To do that, call
|
||||
kobject_put(). By doing this, the kobject core will automatically clean up
|
||||
all of the memory allocated by this kobject. If a KOBJ_ADD uevent has been
|
||||
sent for the object, a corresponding KOBJ_REMOVE uevent will be sent, and
|
||||
all of the memory allocated by this kobject. If a ``KOBJ_ADD`` uevent has been
|
||||
sent for the object, a corresponding ``KOBJ_REMOVE`` uevent will be sent, and
|
||||
any other sysfs housekeeping will be handled for the caller properly.
|
||||
|
||||
If you need to do a two-stage delete of the kobject (say you are not
|
||||
|
@ -430,5 +430,5 @@ Example code to copy from
|
|||
=========================
|
||||
|
||||
For a more complete example of using ksets and kobjects properly, see the
|
||||
example programs samples/kobject/{kobject-example.c,kset-example.c},
|
||||
which will be built as loadable modules if you select CONFIG_SAMPLE_KOBJECT.
|
||||
example programs ``samples/kobject/{kobject-example.c,kset-example.c}``,
|
||||
which will be built as loadable modules if you select ``CONFIG_SAMPLE_KOBJECT``.
|
||||
|
|
Loading…
Reference in New Issue