| 
									
										
										
										
											2006-09-29 01:59:00 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright 2006, Red Hat, Inc., Dave Jones | 
					
						
							|  |  |  |  * Released under the General Public License (GPL). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file contains the linked list implementations for | 
					
						
							|  |  |  |  * DEBUG_LIST. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-16 21:29:17 -05:00
										 |  |  | #include <linux/export.h>
 | 
					
						
							| 
									
										
										
										
											2006-09-29 01:59:00 -07:00
										 |  |  | #include <linux/list.h>
 | 
					
						
							| 
									
										
										
										
											2012-01-20 18:35:53 -05:00
										 |  |  | #include <linux/bug.h>
 | 
					
						
							| 
									
										
										
										
											2012-01-20 18:46:49 -05:00
										 |  |  | #include <linux/kernel.h>
 | 
					
						
							| 
									
										
										
										
											2012-03-14 22:17:39 -04:00
										 |  |  | #include <linux/rculist.h>
 | 
					
						
							| 
									
										
										
										
											2006-09-29 01:59:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Insert a new entry between two known consecutive entries. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This is only for internal list manipulation where we know | 
					
						
							|  |  |  |  * the prev/next entries already! | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void __list_add(struct list_head *new, | 
					
						
							|  |  |  | 			      struct list_head *prev, | 
					
						
							|  |  |  | 			      struct list_head *next) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-25 01:45:55 -07:00
										 |  |  | 	WARN(next->prev != prev, | 
					
						
							|  |  |  | 		"list_add corruption. next->prev should be " | 
					
						
							|  |  |  | 		"prev (%p), but was %p. (next=%p).\n", | 
					
						
							|  |  |  | 		prev, next->prev, next); | 
					
						
							|  |  |  | 	WARN(prev->next != next, | 
					
						
							|  |  |  | 		"list_add corruption. prev->next should be " | 
					
						
							|  |  |  | 		"next (%p), but was %p. (prev=%p).\n", | 
					
						
							|  |  |  | 		next, prev->next, prev); | 
					
						
							| 
									
										
										
										
											2012-05-29 15:07:31 -07:00
										 |  |  | 	WARN(new == prev || new == next, | 
					
						
							|  |  |  | 	     "list_add double add: new=%p, prev=%p, next=%p.\n", | 
					
						
							|  |  |  | 	     new, prev, next); | 
					
						
							| 
									
										
										
										
											2006-09-29 01:59:00 -07:00
										 |  |  | 	next->prev = new; | 
					
						
							|  |  |  | 	new->next = next; | 
					
						
							|  |  |  | 	new->prev = prev; | 
					
						
							|  |  |  | 	prev->next = new; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(__list_add); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-18 11:32:28 -08:00
										 |  |  | void __list_del_entry(struct list_head *entry) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct list_head *prev, *next; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	prev = entry->prev; | 
					
						
							|  |  |  | 	next = entry->next; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (WARN(next == LIST_POISON1, | 
					
						
							|  |  |  | 		"list_del corruption, %p->next is LIST_POISON1 (%p)\n", | 
					
						
							|  |  |  | 		entry, LIST_POISON1) || | 
					
						
							|  |  |  | 	    WARN(prev == LIST_POISON2, | 
					
						
							|  |  |  | 		"list_del corruption, %p->prev is LIST_POISON2 (%p)\n", | 
					
						
							|  |  |  | 		entry, LIST_POISON2) || | 
					
						
							|  |  |  | 	    WARN(prev->next != entry, | 
					
						
							|  |  |  | 		"list_del corruption. prev->next should be %p, " | 
					
						
							|  |  |  | 		"but was %p\n", entry, prev->next) || | 
					
						
							|  |  |  | 	    WARN(next->prev != entry, | 
					
						
							|  |  |  | 		"list_del corruption. next->prev should be %p, " | 
					
						
							|  |  |  | 		"but was %p\n", entry, next->prev)) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__list_del(prev, next); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(__list_del_entry); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-29 01:59:00 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * list_del - deletes entry from list. | 
					
						
							|  |  |  |  * @entry: the element to delete from the list. | 
					
						
							|  |  |  |  * Note: list_empty on entry does not return true after this, the entry is | 
					
						
							|  |  |  |  * in an undefined state. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void list_del(struct list_head *entry) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-18 11:32:28 -08:00
										 |  |  | 	__list_del_entry(entry); | 
					
						
							| 
									
										
										
										
											2006-09-29 01:59:00 -07:00
										 |  |  | 	entry->next = LIST_POISON1; | 
					
						
							|  |  |  | 	entry->prev = LIST_POISON2; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(list_del); | 
					
						
							| 
									
										
										
										
											2012-03-14 22:17:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * RCU variants. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void __list_add_rcu(struct list_head *new, | 
					
						
							|  |  |  | 		    struct list_head *prev, struct list_head *next) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	WARN(next->prev != prev, | 
					
						
							| 
									
										
										
										
											2012-05-17 15:12:45 -07:00
										 |  |  | 		"list_add_rcu corruption. next->prev should be prev (%p), but was %p. (next=%p).\n", | 
					
						
							| 
									
										
										
										
											2012-03-14 22:17:39 -04:00
										 |  |  | 		prev, next->prev, next); | 
					
						
							|  |  |  | 	WARN(prev->next != next, | 
					
						
							| 
									
										
										
										
											2012-05-17 15:12:45 -07:00
										 |  |  | 		"list_add_rcu corruption. prev->next should be next (%p), but was %p. (prev=%p).\n", | 
					
						
							| 
									
										
										
										
											2012-03-14 22:17:39 -04:00
										 |  |  | 		next, prev->next, prev); | 
					
						
							|  |  |  | 	new->next = next; | 
					
						
							|  |  |  | 	new->prev = prev; | 
					
						
							|  |  |  | 	rcu_assign_pointer(list_next_rcu(prev), new); | 
					
						
							|  |  |  | 	next->prev = new; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(__list_add_rcu); |