[PATCH 2/6] list: add new MACROs to make iterator invisiable outside the loop

From: Xiaomeng Tong
Date: Tue Mar 01 2022 - 02:59:13 EST


For each list_for_each_entry* macros(10 variants), implements a respective
new *_inside one. Such as the new macro list_for_each_entry_inside for
list_for_each_entry. The idea is to be as compatible with the original
interface as possible and to minimize code changes.

Here are 2 examples:

list_for_each_entry_inside:
- declare the iterator-variable pos inside the loop. Thus, the origin
declare of the inputed *pos* outside the loop should be removed. In
other words, the inputed *pos* now is just a string name.
- add a new "type" argument as the type of the container struct this is
embedded in, and should be inputed when calling the macro.

list_for_each_entry_safe_continue_inside:
- declare the iterator-variable pos and n inside the loop. Thus, the
origin declares of the inputed *pos* and *n* outside the loop should
be removed. In other words, the inputed *pos* and *n* now are just
string name.
- add a new "start" argument as the given iterator to start with and
can be used to get the container struct *type*. This should be inputed
when calling the macro.

Signed-off-by: Xiaomeng Tong <xiam0nd.tong@xxxxxxxxx>
---
include/linux/list.h | 156 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 156 insertions(+)

diff --git a/include/linux/list.h b/include/linux/list.h
index dd6c2041d..1595ce865 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -639,6 +639,19 @@ static inline void list_splice_tail_init(struct list_head *list,
!list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member))

+/**
+ * list_for_each_entry_inside
+ * - iterate over list of given type and keep iterator inside the loop
+ * @pos: the type * to use as a loop cursor.
+ * @type: the type of the container struct this is embedded in.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_for_each_entry_inside(pos, type, head, member) \
+ for (type * pos = list_first_entry(head, type, member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = list_next_entry(pos, member))
+
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop cursor.
@@ -650,6 +663,19 @@ static inline void list_splice_tail_init(struct list_head *list,
!list_entry_is_head(pos, head, member); \
pos = list_prev_entry(pos, member))

+/**
+ * list_for_each_entry_reverse_inside
+ * - iterate backwards over list of given type and keep iterator inside the loop.
+ * @pos: the type * to use as a loop cursor.
+ * @type: the type of the container struct this is embedded in.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_for_each_entry_reverse_inside(pos, type, head, member) \
+ for (type * pos = list_last_entry(head, type, member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = list_prev_entry(pos, member))
+
/**
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
* @pos: the type * to use as a start point
@@ -675,6 +701,22 @@ static inline void list_splice_tail_init(struct list_head *list,
!list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member))

+/**
+ * list_for_each_entry_continue_inside
+ * - continue iteration over list of given type and keep iterator inside the loop
+ * @pos: the type * to use as a loop cursor.
+ * @start: the given iterator to start with.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_inside(pos, start, head, member) \
+ for (typeof(*start) *pos = list_next_entry(start, member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = list_next_entry(pos, member))
+
/**
* list_for_each_entry_continue_reverse - iterate backwards from the given point
* @pos: the type * to use as a loop cursor.
@@ -689,6 +731,22 @@ static inline void list_splice_tail_init(struct list_head *list,
!list_entry_is_head(pos, head, member); \
pos = list_prev_entry(pos, member))

+/**
+ * list_for_each_entry_continue_reverse_inside
+ * - iterate backwards from the given point and keep iterator inside the loop
+ * @pos: the type * to use as a loop cursor.
+ * @start: the given iterator to start with.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Start to iterate over list of given type backwards, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_reverse_inside(pos, start, head, member) \
+ for (typeof(*start) *pos = list_prev_entry(start, member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = list_prev_entry(pos, member))
+
/**
* list_for_each_entry_from - iterate over list of given type from the current point
* @pos: the type * to use as a loop cursor.
@@ -701,6 +759,20 @@ static inline void list_splice_tail_init(struct list_head *list,
for (; !list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member))

+/**
+ * list_for_each_entry_from_inside
+ * - iterate over list of given type from the current point and keep iterator inside the loop
+ * @pos: the type * to use as a loop cursor.
+ * @start: the given iterator to start with.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from_inside(pos, start, head, member) \
+ for (typeof(*start) *pos = start; !list_entry_is_head(pos, head, member); \
+ pos = list_next_entry(pos, member))
+
/**
* list_for_each_entry_from_reverse - iterate backwards over list of given type
* from the current point
@@ -714,6 +786,21 @@ static inline void list_splice_tail_init(struct list_head *list,
for (; !list_entry_is_head(pos, head, member); \
pos = list_prev_entry(pos, member))

+/**
+ * list_for_each_entry_from_reverse_inside
+ * - iterate backwards over list of given type from the current point
+ * and keep iterator inside the loop
+ * @pos: the type * to use as a loop cursor.
+ * @start: the given iterator to start with.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Iterate backwards over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from_reverse_inside(pos, start, head, member) \
+ for (typeof(*start) *pos = start; !list_entry_is_head(pos, head, member); \
+ pos = list_prev_entry(pos, member))
+
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
@@ -727,6 +814,22 @@ static inline void list_splice_tail_init(struct list_head *list,
!list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member))

+/**
+ * list_for_each_entry_safe_inside
+ * - iterate over list of given type safe against removal of list entry
+ * and keep iterator inside the loop
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @type: the type of the container struct this is embedded in.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_for_each_entry_safe_inside(pos, n, type, head, member) \
+ for (type * pos = list_first_entry(head, type, member), \
+ *n = list_next_entry(pos, member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = n, n = list_next_entry(n, member))
+
/**
* list_for_each_entry_safe_continue - continue list iteration safe against removal
* @pos: the type * to use as a loop cursor.
@@ -743,6 +846,24 @@ static inline void list_splice_tail_init(struct list_head *list,
!list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member))

+/**
+ * list_for_each_entry_safe_continue_inside
+ * - continue list iteration safe against removal and keep iterator inside the loop
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @start: the given iterator to start with.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue_inside(pos, n, start, head, member) \
+ for (typeof(*start) *pos = list_next_entry(start, member), \
+ *n = list_next_entry(pos, member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = n, n = list_next_entry(n, member))
+
/**
* list_for_each_entry_safe_from - iterate over list from current point safe against removal
* @pos: the type * to use as a loop cursor.
@@ -758,6 +879,23 @@ static inline void list_splice_tail_init(struct list_head *list,
!list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member))

+/**
+ * list_for_each_entry_safe_from_inside
+ * - iterate over list from current point safe against removal and keep iterator inside the loop
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @start: the given iterator to start with.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from_inside(pos, n, start, head, member) \
+ for (typeof(*start) *pos = start, *n = list_next_entry(pos, member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = n, n = list_next_entry(n, member))
+
/**
* list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
* @pos: the type * to use as a loop cursor.
@@ -774,6 +912,24 @@ static inline void list_splice_tail_init(struct list_head *list,
!list_entry_is_head(pos, head, member); \
pos = n, n = list_prev_entry(n, member))

+/**
+ * list_for_each_entry_safe_reverse_insde
+ * - iterate backwards over list safe against removal and keep iterator inside the loop
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @type: the type of the struct this is enmbeded in.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse_inside(pos, n, type, head, member) \
+ for (type * pos = list_last_entry(head, type, member), \
+ *n = list_prev_entry(pos, member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = n, n = list_prev_entry(n, member))
+
/**
* list_safe_reset_next - reset a stale list_for_each_entry_safe loop
* @pos: the loop cursor used in the list_for_each_entry_safe loop
--
2.17.1