Btrfs-progs: introduce list_{first, next}_entry/list_splice_tail{_init}

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
This commit is contained in:
Miao Xie 2013-07-03 21:25:18 +08:00 committed by Chris Mason
parent 30d5c8a49f
commit 68acb1075e
1 changed files with 59 additions and 9 deletions

68
list.h
View File

@ -223,18 +223,18 @@ static inline int list_empty_careful(const struct list_head *head)
return (next == head) && (next == head->prev); return (next == head) && (next == head->prev);
} }
static inline void __list_splice(struct list_head *list, static inline void __list_splice(const struct list_head *list,
struct list_head *head) struct list_head *prev,
struct list_head *next)
{ {
struct list_head *first = list->next; struct list_head *first = list->next;
struct list_head *last = list->prev; struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head; first->prev = prev;
head->next = first; prev->next = first;
last->next = at; last->next = next;
at->prev = last; next->prev = last;
} }
/** /**
@ -245,7 +245,19 @@ static inline void __list_splice(struct list_head *list,
static inline void list_splice(struct list_head *list, struct list_head *head) static inline void list_splice(struct list_head *list, struct list_head *head)
{ {
if (!list_empty(list)) if (!list_empty(list))
__list_splice(list, head); __list_splice(list, head, head->next);
}
/**
* list_splice_tail - join two lists, each list being a queue
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice_tail(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head->prev, head);
} }
/** /**
@ -259,7 +271,24 @@ static inline void list_splice_init(struct list_head *list,
struct list_head *head) struct list_head *head)
{ {
if (!list_empty(list)) { if (!list_empty(list)) {
__list_splice(list, head); __list_splice(list, head, head->next);
INIT_LIST_HEAD(list);
}
}
/**
* list_splice_tail_init - join two lists and reinitialise the emptied list
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* Each of the lists is a queue.
* The list at @list is reinitialised
*/
static inline void list_splice_tail_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head->prev, head);
INIT_LIST_HEAD(list); INIT_LIST_HEAD(list);
} }
} }
@ -273,6 +302,27 @@ static inline void list_splice_init(struct list_head *list,
#define list_entry(ptr, type, member) \ #define list_entry(ptr, type, member) \
container_of(ptr, type, member) container_of(ptr, type, member)
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_next_entry - get the next element from a list
* @ptr: the list head to take the element from.
* @member: the name of the list_struct within the struct.
*
* Note, that next is expected to be not null.
*/
#define list_next_entry(ptr, member) \
list_entry((ptr)->member.next, typeof(*ptr), member)
/** /**
* list_for_each - iterate over a list * list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor. * @pos: the &struct list_head to use as a loop cursor.