diff options
Diffstat (limited to 'lib/list_debug.c')
-rw-r--r-- | lib/list_debug.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/lib/list_debug.c b/lib/list_debug.c new file mode 100644 index 000000000000..1aae85cef92c --- /dev/null +++ b/lib/list_debug.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * Copyright 2006, Red Hat, Inc., Dave Jones | ||
3 | * Released under the General Public License (GPL). | ||
4 | * | ||
5 | * This file contains the linked list implementations for | ||
6 | * DEBUG_LIST. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/list.h> | ||
11 | |||
12 | /* | ||
13 | * Insert a new entry between two known consecutive entries. | ||
14 | * | ||
15 | * This is only for internal list manipulation where we know | ||
16 | * the prev/next entries already! | ||
17 | */ | ||
18 | |||
19 | void __list_add(struct list_head *new, | ||
20 | struct list_head *prev, | ||
21 | struct list_head *next) | ||
22 | { | ||
23 | if (unlikely(next->prev != prev)) { | ||
24 | printk(KERN_ERR "list_add corruption. next->prev should be %p, but was %p\n", | ||
25 | prev, next->prev); | ||
26 | BUG(); | ||
27 | } | ||
28 | if (unlikely(prev->next != next)) { | ||
29 | printk(KERN_ERR "list_add corruption. prev->next should be %p, but was %p\n", | ||
30 | next, prev->next); | ||
31 | BUG(); | ||
32 | } | ||
33 | next->prev = new; | ||
34 | new->next = next; | ||
35 | new->prev = prev; | ||
36 | prev->next = new; | ||
37 | } | ||
38 | EXPORT_SYMBOL(__list_add); | ||
39 | |||
40 | /** | ||
41 | * list_add - add a new entry | ||
42 | * @new: new entry to be added | ||
43 | * @head: list head to add it after | ||
44 | * | ||
45 | * Insert a new entry after the specified head. | ||
46 | * This is good for implementing stacks. | ||
47 | */ | ||
48 | void list_add(struct list_head *new, struct list_head *head) | ||
49 | { | ||
50 | __list_add(new, head, head->next); | ||
51 | } | ||
52 | EXPORT_SYMBOL(list_add); | ||
53 | |||
54 | /** | ||
55 | * list_del - deletes entry from list. | ||
56 | * @entry: the element to delete from the list. | ||
57 | * Note: list_empty on entry does not return true after this, the entry is | ||
58 | * in an undefined state. | ||
59 | */ | ||
60 | void list_del(struct list_head *entry) | ||
61 | { | ||
62 | if (unlikely(entry->prev->next != entry)) { | ||
63 | printk(KERN_ERR "list_del corruption. prev->next should be %p, but was %p\n", | ||
64 | entry, entry->prev->next); | ||
65 | BUG(); | ||
66 | } | ||
67 | if (unlikely(entry->next->prev != entry)) { | ||
68 | printk(KERN_ERR "list_del corruption. next->prev should be %p, but was %p\n", | ||
69 | entry, entry->next->prev); | ||
70 | BUG(); | ||
71 | } | ||
72 | __list_del(entry->prev, entry->next); | ||
73 | entry->next = LIST_POISON1; | ||
74 | entry->prev = LIST_POISON2; | ||
75 | } | ||
76 | EXPORT_SYMBOL(list_del); | ||
77 | |||