diff options
| -rw-r--r-- | include/linux/klist.h | 30 | ||||
| -rw-r--r-- | lib/klist.c | 206 |
2 files changed, 100 insertions, 136 deletions
diff --git a/include/linux/klist.h b/include/linux/klist.h index b49385f13419..06c338ef7f1b 100644 --- a/include/linux/klist.h +++ b/include/linux/klist.h | |||
| @@ -34,38 +34,38 @@ struct klist { | |||
| 34 | #define DEFINE_KLIST(_name, _get, _put) \ | 34 | #define DEFINE_KLIST(_name, _get, _put) \ |
| 35 | struct klist _name = KLIST_INIT(_name, _get, _put) | 35 | struct klist _name = KLIST_INIT(_name, _get, _put) |
| 36 | 36 | ||
| 37 | extern void klist_init(struct klist * k, void (*get)(struct klist_node *), | 37 | extern void klist_init(struct klist *k, void (*get)(struct klist_node *), |
| 38 | void (*put)(struct klist_node *)); | 38 | void (*put)(struct klist_node *)); |
| 39 | 39 | ||
| 40 | struct klist_node { | 40 | struct klist_node { |
| 41 | struct klist * n_klist; | 41 | struct klist *n_klist; |
| 42 | struct list_head n_node; | 42 | struct list_head n_node; |
| 43 | struct kref n_ref; | 43 | struct kref n_ref; |
| 44 | struct completion n_removed; | 44 | struct completion n_removed; |
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | extern void klist_add_tail(struct klist_node * n, struct klist * k); | 47 | extern void klist_add_tail(struct klist_node *n, struct klist *k); |
| 48 | extern void klist_add_head(struct klist_node * n, struct klist * k); | 48 | extern void klist_add_head(struct klist_node *n, struct klist *k); |
| 49 | extern void klist_add_after(struct klist_node *n, struct klist_node *pos); | 49 | extern void klist_add_after(struct klist_node *n, struct klist_node *pos); |
| 50 | extern void klist_add_before(struct klist_node *n, struct klist_node *pos); | 50 | extern void klist_add_before(struct klist_node *n, struct klist_node *pos); |
| 51 | 51 | ||
| 52 | extern void klist_del(struct klist_node * n); | 52 | extern void klist_del(struct klist_node *n); |
| 53 | extern void klist_remove(struct klist_node * n); | 53 | extern void klist_remove(struct klist_node *n); |
| 54 | 54 | ||
| 55 | extern int klist_node_attached(struct klist_node * n); | 55 | extern int klist_node_attached(struct klist_node *n); |
| 56 | 56 | ||
| 57 | 57 | ||
| 58 | struct klist_iter { | 58 | struct klist_iter { |
| 59 | struct klist * i_klist; | 59 | struct klist *i_klist; |
| 60 | struct list_head * i_head; | 60 | struct list_head *i_head; |
| 61 | struct klist_node * i_cur; | 61 | struct klist_node *i_cur; |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | 64 | ||
| 65 | extern void klist_iter_init(struct klist * k, struct klist_iter * i); | 65 | extern void klist_iter_init(struct klist *k, struct klist_iter *i); |
| 66 | extern void klist_iter_init_node(struct klist * k, struct klist_iter * i, | 66 | extern void klist_iter_init_node(struct klist *k, struct klist_iter *i, |
| 67 | struct klist_node * n); | 67 | struct klist_node *n); |
| 68 | extern void klist_iter_exit(struct klist_iter * i); | 68 | extern void klist_iter_exit(struct klist_iter *i); |
| 69 | extern struct klist_node * klist_next(struct klist_iter * i); | 69 | extern struct klist_node *klist_next(struct klist_iter *i); |
| 70 | 70 | ||
| 71 | #endif | 71 | #endif |
diff --git a/lib/klist.c b/lib/klist.c index ebba9488046e..cca37f96faa2 100644 --- a/lib/klist.c +++ b/lib/klist.c | |||
| @@ -1,38 +1,37 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * klist.c - Routines for manipulating klists. | 2 | * klist.c - Routines for manipulating klists. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005 Patrick Mochel | ||
| 4 | * | 5 | * |
| 5 | * This klist interface provides a couple of structures that wrap around | 6 | * This file is released under the GPL v2. |
| 6 | * struct list_head to provide explicit list "head" (struct klist) and | ||
| 7 | * list "node" (struct klist_node) objects. For struct klist, a spinlock | ||
| 8 | * is included that protects access to the actual list itself. struct | ||
| 9 | * klist_node provides a pointer to the klist that owns it and a kref | ||
| 10 | * reference count that indicates the number of current users of that node | ||
| 11 | * in the list. | ||
| 12 | * | 7 | * |
| 13 | * The entire point is to provide an interface for iterating over a list | 8 | * This klist interface provides a couple of structures that wrap around |
| 14 | * that is safe and allows for modification of the list during the | 9 | * struct list_head to provide explicit list "head" (struct klist) and list |
| 15 | * iteration (e.g. insertion and removal), including modification of the | 10 | * "node" (struct klist_node) objects. For struct klist, a spinlock is |
| 16 | * current node on the list. | 11 | * included that protects access to the actual list itself. struct |
| 12 | * klist_node provides a pointer to the klist that owns it and a kref | ||
| 13 | * reference count that indicates the number of current users of that node | ||
| 14 | * in the list. | ||
| 17 | * | 15 | * |
| 18 | * It works using a 3rd object type - struct klist_iter - that is declared | 16 | * The entire point is to provide an interface for iterating over a list |
| 19 | * and initialized before an iteration. klist_next() is used to acquire the | 17 | * that is safe and allows for modification of the list during the |
| 20 | * next element in the list. It returns NULL if there are no more items. | 18 | * iteration (e.g. insertion and removal), including modification of the |
| 21 | * Internally, that routine takes the klist's lock, decrements the reference | 19 | * current node on the list. |
| 22 | * count of the previous klist_node and increments the count of the next | ||
| 23 | * klist_node. It then drops the lock and returns. | ||
| 24 | * | 20 | * |
| 25 | * There are primitives for adding and removing nodes to/from a klist. | 21 | * It works using a 3rd object type - struct klist_iter - that is declared |
| 26 | * When deleting, klist_del() will simply decrement the reference count. | 22 | * and initialized before an iteration. klist_next() is used to acquire the |
| 27 | * Only when the count goes to 0 is the node removed from the list. | 23 | * next element in the list. It returns NULL if there are no more items. |
| 28 | * klist_remove() will try to delete the node from the list and block | 24 | * Internally, that routine takes the klist's lock, decrements the |
| 29 | * until it is actually removed. This is useful for objects (like devices) | 25 | * reference count of the previous klist_node and increments the count of |
| 30 | * that have been removed from the system and must be freed (but must wait | 26 | * the next klist_node. It then drops the lock and returns. |
| 31 | * until all accessors have finished). | ||
| 32 | * | 27 | * |
| 33 | * Copyright (C) 2005 Patrick Mochel | 28 | * There are primitives for adding and removing nodes to/from a klist. |
| 34 | * | 29 | * When deleting, klist_del() will simply decrement the reference count. |
| 35 | * This file is released under the GPL v2. | 30 | * Only when the count goes to 0 is the node removed from the list. |
| 31 | * klist_remove() will try to delete the node from the list and block until | ||
| 32 | * it is actually removed. This is useful for objects (like devices) that | ||
| 33 | * have been removed from the system and must be freed (but must wait until | ||
| 34 | * all accessors have finished). | ||
| 36 | */ | 35 | */ |
| 37 | 36 | ||
| 38 | #include <linux/klist.h> | 37 | #include <linux/klist.h> |
| @@ -40,10 +39,10 @@ | |||
| 40 | 39 | ||
| 41 | 40 | ||
| 42 | /** | 41 | /** |
| 43 | * klist_init - Initialize a klist structure. | 42 | * klist_init - Initialize a klist structure. |
| 44 | * @k: The klist we're initializing. | 43 | * @k: The klist we're initializing. |
| 45 | * @get: The get function for the embedding object (NULL if none) | 44 | * @get: The get function for the embedding object (NULL if none) |
| 46 | * @put: The put function for the embedding object (NULL if none) | 45 | * @put: The put function for the embedding object (NULL if none) |
| 47 | * | 46 | * |
| 48 | * Initialises the klist structure. If the klist_node structures are | 47 | * Initialises the klist structure. If the klist_node structures are |
| 49 | * going to be embedded in refcounted objects (necessary for safe | 48 | * going to be embedded in refcounted objects (necessary for safe |
| @@ -51,8 +50,7 @@ | |||
| 51 | * functions that take and release references on the embedding | 50 | * functions that take and release references on the embedding |
| 52 | * objects. | 51 | * objects. |
| 53 | */ | 52 | */ |
| 54 | 53 | void klist_init(struct klist *k, void (*get)(struct klist_node *), | |
| 55 | void klist_init(struct klist * k, void (*get)(struct klist_node *), | ||
| 56 | void (*put)(struct klist_node *)) | 54 | void (*put)(struct klist_node *)) |
| 57 | { | 55 | { |
| 58 | INIT_LIST_HEAD(&k->k_list); | 56 | INIT_LIST_HEAD(&k->k_list); |
| @@ -60,26 +58,23 @@ void klist_init(struct klist * k, void (*get)(struct klist_node *), | |||
| 60 | k->get = get; | 58 | k->get = get; |
| 61 | k->put = put; | 59 | k->put = put; |
| 62 | } | 60 | } |
| 63 | |||
| 64 | EXPORT_SYMBOL_GPL(klist_init); | 61 | EXPORT_SYMBOL_GPL(klist_init); |
| 65 | 62 | ||
| 66 | 63 | static void add_head(struct klist *k, struct klist_node *n) | |
| 67 | static void add_head(struct klist * k, struct klist_node * n) | ||
| 68 | { | 64 | { |
| 69 | spin_lock(&k->k_lock); | 65 | spin_lock(&k->k_lock); |
| 70 | list_add(&n->n_node, &k->k_list); | 66 | list_add(&n->n_node, &k->k_list); |
| 71 | spin_unlock(&k->k_lock); | 67 | spin_unlock(&k->k_lock); |
| 72 | } | 68 | } |
| 73 | 69 | ||
| 74 | static void add_tail(struct klist * k, struct klist_node * n) | 70 | static void add_tail(struct klist *k, struct klist_node *n) |
| 75 | { | 71 | { |
| 76 | spin_lock(&k->k_lock); | 72 | spin_lock(&k->k_lock); |
| 77 | list_add_tail(&n->n_node, &k->k_list); | 73 | list_add_tail(&n->n_node, &k->k_list); |
| 78 | spin_unlock(&k->k_lock); | 74 | spin_unlock(&k->k_lock); |
| 79 | } | 75 | } |
| 80 | 76 | ||
| 81 | 77 | static void klist_node_init(struct klist *k, struct klist_node *n) | |
| 82 | static void klist_node_init(struct klist * k, struct klist_node * n) | ||
| 83 | { | 78 | { |
| 84 | INIT_LIST_HEAD(&n->n_node); | 79 | INIT_LIST_HEAD(&n->n_node); |
| 85 | init_completion(&n->n_removed); | 80 | init_completion(&n->n_removed); |
| @@ -89,37 +84,30 @@ static void klist_node_init(struct klist * k, struct klist_node * n) | |||
| 89 | k->get(n); | 84 | k->get(n); |
| 90 | } | 85 | } |
| 91 | 86 | ||
| 92 | |||
| 93 | /** | 87 | /** |
| 94 | * klist_add_head - Initialize a klist_node and add it to front. | 88 | * klist_add_head - Initialize a klist_node and add it to front. |
| 95 | * @n: node we're adding. | 89 | * @n: node we're adding. |
| 96 | * @k: klist it's going on. | 90 | * @k: klist it's going on. |
