root/include/linux/list_private.h
/* SPDX-License-Identifier: GPL-2.0 */

/*
 * Copyright (c) 2025, Google LLC.
 * Pasha Tatashin <pasha.tatashin@soleen.com>
 */
#ifndef _LINUX_LIST_PRIVATE_H
#define _LINUX_LIST_PRIVATE_H

/**
 * DOC: Private List Primitives
 *
 * Provides a set of list primitives identical in function to those in
 * ``<linux/list.h>``, but designed for cases where the embedded
 * ``&struct list_head`` is private member.
 */

#include <linux/compiler.h>
#include <linux/list.h>

#define __list_private_offset(type, member)                                     \
        ((size_t)(&ACCESS_PRIVATE(((type *)0), member)))

/**
 * list_private_entry - get the struct for this entry
 * @ptr:        the &struct list_head pointer.
 * @type:       the type of the struct this is embedded in.
 * @member:     the identifier passed to ACCESS_PRIVATE.
 */
#define list_private_entry(ptr, type, member) ({                                \
        const struct list_head *__mptr = (ptr);                                 \
        (type *)((char *)__mptr - __list_private_offset(type, member));         \
})

/**
 * list_private_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 identifier passed to ACCESS_PRIVATE.
 */
#define list_private_first_entry(ptr, type, member)                             \
        list_private_entry((ptr)->next, type, member)

/**
 * list_private_last_entry - get the last 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 identifier passed to ACCESS_PRIVATE.
 */
#define list_private_last_entry(ptr, type, member)                              \
        list_private_entry((ptr)->prev, type, member)

/**
 * list_private_next_entry - get the next element in list
 * @pos:        the type * to cursor
 * @member:     the name of the list_head within the struct.
 */
#define list_private_next_entry(pos, member)                                    \
        list_private_entry(ACCESS_PRIVATE(pos, member).next, typeof(*(pos)), member)

/**
 * list_private_next_entry_circular - get the next element in list
 * @pos:        the type * to cursor.
 * @head:       the list head to take the element from.
 * @member:     the name of the list_head within the struct.
 *
 * Wraparound if pos is the last element (return the first element).
 * Note, that list is expected to be not empty.
 */
#define list_private_next_entry_circular(pos, head, member)                     \
        (list_is_last(&ACCESS_PRIVATE(pos, member), head) ?                     \
        list_private_first_entry(head, typeof(*(pos)), member) :                \
        list_private_next_entry(pos, member))

/**
 * list_private_prev_entry - get the prev element in list
 * @pos:        the type * to cursor
 * @member:     the name of the list_head within the struct.
 */
#define list_private_prev_entry(pos, member)                                    \
        list_private_entry(ACCESS_PRIVATE(pos, member).prev, typeof(*(pos)), member)

/**
 * list_private_prev_entry_circular - get the prev element in list
 * @pos:        the type * to cursor.
 * @head:       the list head to take the element from.
 * @member:     the name of the list_head within the struct.
 *
 * Wraparound if pos is the first element (return the last element).
 * Note, that list is expected to be not empty.
 */
#define list_private_prev_entry_circular(pos, head, member)                     \
        (list_is_first(&ACCESS_PRIVATE(pos, member), head) ?                    \
        list_private_last_entry(head, typeof(*(pos)), member) :                 \
        list_private_prev_entry(pos, member))

/**
 * list_private_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_private_entry_is_head(pos, head, member)                           \
        list_is_head(&ACCESS_PRIVATE(pos, member), (head))

/**
 * list_private_for_each_entry - iterate over list of given type
 * @pos:        the type * to use as a loop cursor.
 * @head:       the head for your list.
 * @member:     the name of the list_head within the struct.
 */
#define list_private_for_each_entry(pos, head, member)                          \
        for (pos = list_private_first_entry(head, typeof(*pos), member);        \
             !list_private_entry_is_head(pos, head, member);                    \
             pos = list_private_next_entry(pos, member))

/**
 * list_private_for_each_entry_reverse - iterate backwards over list of given type.
 * @pos:        the type * to use as a loop cursor.
 * @head:       the head for your list.
 * @member:     the name of the list_head within the struct.
 */
#define list_private_for_each_entry_reverse(pos, head, member)                  \
        for (pos = list_private_last_entry(head, typeof(*pos), member);         \
             !list_private_entry_is_head(pos, head, member);                    \
             pos = list_private_prev_entry(pos, member))

/**
 * list_private_for_each_entry_continue - continue iteration over list of given type
 * @pos:        the type * to use as a loop cursor.
 * @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_private_for_each_entry_continue(pos, head, member)                 \
        for (pos = list_private_next_entry(pos, member);                        \
             !list_private_entry_is_head(pos, head, member);                    \
             pos = list_private_next_entry(pos, member))

/**
 * list_private_for_each_entry_continue_reverse - iterate backwards from the given point
 * @pos:        the type * to use as a loop cursor.
 * @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_private_for_each_entry_continue_reverse(pos, head, member)         \
        for (pos = list_private_prev_entry(pos, member);                        \
             !list_private_entry_is_head(pos, head, member);                    \
             pos = list_private_prev_entry(pos, member))

/**
 * list_private_for_each_entry_from - iterate over list of given type from the current point
 * @pos:        the type * to use as a loop cursor.
 * @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_private_for_each_entry_from(pos, head, member)                     \
        for (; !list_private_entry_is_head(pos, head, member);                  \
             pos = list_private_next_entry(pos, member))

/**
 * list_private_for_each_entry_from_reverse - iterate backwards over list of given type
 *                                    from the current point
 * @pos:        the type * to use as a loop cursor.
 * @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_private_for_each_entry_from_reverse(pos, head, member)             \
        for (; !list_private_entry_is_head(pos, head, member);                  \
             pos = list_private_prev_entry(pos, member))

/**
 * list_private_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.
 * @n:          another type * to use as temporary storage
 * @head:       the head for your list.
 * @member:     the name of the list_head within the struct.
 */
#define list_private_for_each_entry_safe(pos, n, head, member)                  \
        for (pos = list_private_first_entry(head, typeof(*pos), member),        \
                n = list_private_next_entry(pos, member);                       \
             !list_private_entry_is_head(pos, head, member);                    \
             pos = n, n = list_private_next_entry(n, member))

/**
 * list_private_for_each_entry_safe_continue - continue list iteration safe against removal
 * @pos:        the type * to use as a loop cursor.
 * @n:          another type * to use as temporary storage
 * @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_private_for_each_entry_safe_continue(pos, n, head, member)         \
        for (pos = list_private_next_entry(pos, member),                        \
                n = list_private_next_entry(pos, member);                       \
             !list_private_entry_is_head(pos, head, member);                    \
             pos = n, n = list_private_next_entry(n, member))

/**
 * list_private_for_each_entry_safe_from - iterate over list from current point safe against removal
 * @pos:        the type * to use as a loop cursor.
 * @n:          another type * to use as temporary storage
 * @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_private_for_each_entry_safe_from(pos, n, head, member)             \
        for (n = list_private_next_entry(pos, member);                          \
             !list_private_entry_is_head(pos, head, member);                    \
             pos = n, n = list_private_next_entry(n, member))

/**
 * list_private_for_each_entry_safe_reverse - iterate backwards over list safe against removal
 * @pos:        the type * to use as a loop cursor.
 * @n:          another type * to use as temporary storage
 * @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_private_for_each_entry_safe_reverse(pos, n, head, member)          \
        for (pos = list_private_last_entry(head, typeof(*pos), member),         \
                n = list_private_prev_entry(pos, member);                       \
             !list_private_entry_is_head(pos, head, member);                    \
             pos = n, n = list_private_prev_entry(n, member))

/**
 * list_private_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
 * @n:          temporary storage used in list_for_each_entry_safe
 * @member:     the name of the list_head within the struct.
 *
 * list_safe_reset_next is not safe to use in general if the list may be
 * modified concurrently (eg. the lock is dropped in the loop body). An
 * exception to this is if the cursor element (pos) is pinned in the list,
 * and list_safe_reset_next is called after re-taking the lock and before
 * completing the current iteration of the loop body.
 */
#define list_private_safe_reset_next(pos, n, member)                            \
        n = list_private_next_entry(pos, member)

#endif /* _LINUX_LIST_PRIVATE_H */