summaryrefslogtreecommitdiffstats
path: root/lib/klist.c
AgeCommit message (Collapse)Author
2005-09-07[PATCH] fix klist semantics for lists which have elements removed on traversalJames Bottomley
The problem is that klists claim to provide semantics for safe traversal of lists which are being modified. The failure case is when traversal of a list causes element removal (a fairly common case). The issue is that although the list node is refcounted, if it is embedded in an object (which is universally the case), then the object will be freed regardless of the klist refcount leading to slab corruption because the klist iterator refers to the prior element to get the next. The solution is to make the klist take and release references to the embedding object meaning that the embedding object won't be released until the list relinquishes the reference to it. (akpm: fast-track this because it's needed for the 2.6.13 scsi merge) Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-09-05[PATCH] klist: fix klist to have the same klist_add semantics as list_headJames Bottomley
at the moment, the list_head semantics are list_add(node, head) whereas current klist semantics are klist_add(head, node) This is bound to cause confusion, and since klist is the newcomer, it should follow the list_head semantics. I also added missing include guards to klist.h Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-06-20[PATCH] Don't reference NULL klist pointer in klist_remove().mochel@digitalimplant.org
Signed-off-by: Patrick Mochel <mochel@digitalimplant.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> diff -Nru a/lib/klist.c b/lib/klist.c
2005-06-20[PATCH] add klist_node_attached() to determine if a node is on a list or not.mochel@digitalimplant.org
Signed-off-by: Patrick Mochel <mochel@digitalimplant.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> diff -Nru a/include/linux/klist.h b/include/linux/klist.h
2005-06-20[PATCH] Add initial implementation of klist helpers.mochel@digitalimplant.org
This klist interface provides a couple of structures that wrap around struct list_head to provide explicit list "head" (struct klist) and list "node" (struct klist_node) objects. For struct klist, a spinlock is included that protects access to the actual list itself. struct klist_node provides a pointer to the klist that owns it and a kref reference count that indicates the number of current users of that node in the list. The entire point is to provide an interface for iterating over a list that is safe and allows for modification of the list during the iteration (e.g. insertion and removal), including modification of the current node on the list. It works using a 3rd object type - struct klist_iter - that is declared and initialized before an iteration. klist_next() is used to acquire the next element in the list. It returns NULL if there are no more items. This klist interface provides a couple of structures that wrap around struct list_head to provide explicit list "head" (struct klist) and list "node" (struct klist_node) objects. For struct klist, a spinlock is included that protects access to the actual list itself. struct klist_node provides a pointer to the klist that owns it and a kref reference count that indicates the number of current users of that node in the list. The entire point is to provide an interface for iterating over a list that is safe and allows for modification of the list during the iteration (e.g. insertion and removal), including modification of the current node on the list. It works using a 3rd object type - struct klist_iter - that is declared and initialized before an iteration. klist_next() is used to acquire the next element in the list. It returns NULL if there are no more items. Internally, that routine takes the klist's lock, decrements the reference count of the previous klist_node and increments the count of the next klist_node. It then drops the lock and returns. There are primitives for adding and removing nodes to/from a klist. When deleting, klist_del() will simply decrement the reference count. Only when the count goes to 0 is the node removed from the list. klist_remove() will try to delete the node from the list and block until it is actually removed. This is useful for objects (like devices) that have been removed from the system and must be freed (but must wait until all accessors have finished). Internally, that routine takes the klist's lock, decrements the reference count of the previous klist_node and increments the count of the next klist_node. It then drops the lock and returns. There are primitives for adding and removing nodes to/from a klist. When deleting, klist_del() will simply decrement the reference count. Only when the count goes to 0 is the node removed from the list. klist_remove() will try to delete the node from the list and block until it is actually removed. This is useful for objects (like devices) that have been removed from the system and must be freed (but must wait until all accessors have finished). Signed-off-by: Patrick Mochel <mochel@digitalimplant.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> diff -Nru a/include/linux/klist.h b/include/linux/klist.h