Commit e1308161 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Linus Torvalds

include/linux/list.h: add a macro to test if entry is pointing to the head

Add a macro to test if entry is pointing to the head of the list which is
useful in cases like:

  list_for_each_entry(pos, &head, member) {
    if (cond)
      break;
  }
  if (list_entry_is_head(pos, &head, member))
    return -ERRNO;

that allows to avoid additional variable to be added to track if loop has
not been stopped in the middle.

While here, convert list_for_each_entry*() family of macros to use a new one.
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Reviewed-by: default avatarCezary Rojewski <cezary.rojewski@intel.com>
Link: https://lkml.kernel.org/r/20200929134342.51489-1-andriy.shevchenko@linux.intel.comSigned-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 1d339638
...@@ -609,6 +609,15 @@ static inline void list_splice_tail_init(struct list_head *list, ...@@ -609,6 +609,15 @@ static inline void list_splice_tail_init(struct list_head *list,
pos != (head); \ pos != (head); \
pos = n, n = pos->prev) pos = n, n = pos->prev)
/**
* list_entry_is_head - test if the entry points to the head of the list
* @pos: the type * to cursor
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_entry_is_head(pos, head, member) \
(&pos->member == (head))
/** /**
* list_for_each_entry - iterate over list of given type * list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor. * @pos: the type * to use as a loop cursor.
...@@ -617,7 +626,7 @@ static inline void list_splice_tail_init(struct list_head *list, ...@@ -617,7 +626,7 @@ static inline void list_splice_tail_init(struct list_head *list,
*/ */
#define list_for_each_entry(pos, head, member) \ #define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member); \ for (pos = list_first_entry(head, typeof(*pos), member); \
&pos->member != (head); \ !list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member)) pos = list_next_entry(pos, member))
/** /**
...@@ -628,7 +637,7 @@ static inline void list_splice_tail_init(struct list_head *list, ...@@ -628,7 +637,7 @@ static inline void list_splice_tail_init(struct list_head *list,
*/ */
#define list_for_each_entry_reverse(pos, head, member) \ #define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_last_entry(head, typeof(*pos), member); \ for (pos = list_last_entry(head, typeof(*pos), member); \
&pos->member != (head); \ !list_entry_is_head(pos, head, member); \
pos = list_prev_entry(pos, member)) pos = list_prev_entry(pos, member))
/** /**
...@@ -653,7 +662,7 @@ static inline void list_splice_tail_init(struct list_head *list, ...@@ -653,7 +662,7 @@ static inline void list_splice_tail_init(struct list_head *list,
*/ */
#define list_for_each_entry_continue(pos, head, member) \ #define list_for_each_entry_continue(pos, head, member) \
for (pos = list_next_entry(pos, member); \ for (pos = list_next_entry(pos, member); \
&pos->member != (head); \ !list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member)) pos = list_next_entry(pos, member))
/** /**
...@@ -667,7 +676,7 @@ static inline void list_splice_tail_init(struct list_head *list, ...@@ -667,7 +676,7 @@ static inline void list_splice_tail_init(struct list_head *list,
*/ */
#define list_for_each_entry_continue_reverse(pos, head, member) \ #define list_for_each_entry_continue_reverse(pos, head, member) \
for (pos = list_prev_entry(pos, member); \ for (pos = list_prev_entry(pos, member); \
&pos->member != (head); \ !list_entry_is_head(pos, head, member); \
pos = list_prev_entry(pos, member)) pos = list_prev_entry(pos, member))
/** /**
...@@ -679,7 +688,7 @@ static inline void list_splice_tail_init(struct list_head *list, ...@@ -679,7 +688,7 @@ static inline void list_splice_tail_init(struct list_head *list,
* Iterate over list of given type, continuing from current position. * Iterate over list of given type, continuing from current position.
*/ */
#define list_for_each_entry_from(pos, head, member) \ #define list_for_each_entry_from(pos, head, member) \
for (; &pos->member != (head); \ for (; !list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member)) pos = list_next_entry(pos, member))
/** /**
...@@ -692,7 +701,7 @@ static inline void list_splice_tail_init(struct list_head *list, ...@@ -692,7 +701,7 @@ static inline void list_splice_tail_init(struct list_head *list,
* Iterate backwards over list of given type, continuing from current position. * Iterate backwards over list of given type, continuing from current position.
*/ */
#define list_for_each_entry_from_reverse(pos, head, member) \ #define list_for_each_entry_from_reverse(pos, head, member) \
for (; &pos->member != (head); \ for (; !list_entry_is_head(pos, head, member); \
pos = list_prev_entry(pos, member)) pos = list_prev_entry(pos, member))
/** /**
...@@ -705,7 +714,7 @@ static inline void list_splice_tail_init(struct list_head *list, ...@@ -705,7 +714,7 @@ static inline void list_splice_tail_init(struct list_head *list,
#define list_for_each_entry_safe(pos, n, head, member) \ #define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member), \ for (pos = list_first_entry(head, typeof(*pos), member), \
n = list_next_entry(pos, member); \ n = list_next_entry(pos, member); \
&pos->member != (head); \ !list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member)) pos = n, n = list_next_entry(n, member))
/** /**
...@@ -721,7 +730,7 @@ static inline void list_splice_tail_init(struct list_head *list, ...@@ -721,7 +730,7 @@ static inline void list_splice_tail_init(struct list_head *list,
#define list_for_each_entry_safe_continue(pos, n, head, member) \ #define list_for_each_entry_safe_continue(pos, n, head, member) \
for (pos = list_next_entry(pos, member), \ for (pos = list_next_entry(pos, member), \
n = list_next_entry(pos, member); \ n = list_next_entry(pos, member); \
&pos->member != (head); \ !list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member)) pos = n, n = list_next_entry(n, member))
/** /**
...@@ -736,7 +745,7 @@ static inline void list_splice_tail_init(struct list_head *list, ...@@ -736,7 +745,7 @@ static inline void list_splice_tail_init(struct list_head *list,
*/ */
#define list_for_each_entry_safe_from(pos, n, head, member) \ #define list_for_each_entry_safe_from(pos, n, head, member) \
for (n = list_next_entry(pos, member); \ for (n = list_next_entry(pos, member); \
&pos->member != (head); \ !list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member)) pos = n, n = list_next_entry(n, member))
/** /**
...@@ -752,7 +761,7 @@ static inline void list_splice_tail_init(struct list_head *list, ...@@ -752,7 +761,7 @@ static inline void list_splice_tail_init(struct list_head *list,
#define list_for_each_entry_safe_reverse(pos, n, head, member) \ #define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_last_entry(head, typeof(*pos), member), \ for (pos = list_last_entry(head, typeof(*pos), member), \
n = list_prev_entry(pos, member); \ n = list_prev_entry(pos, member); \
&pos->member != (head); \ !list_entry_is_head(pos, head, member); \
pos = n, n = list_prev_entry(n, member)) pos = n, n = list_prev_entry(n, member))
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment