From: mwilck@suse.com
To: Keith Busch <kbusch@kernel.org>, linux-nvme@lists.infradead.org
Cc: Hannes Reinecke <hare@suse.de>,
Chaitanya Kulkarni <Chaitanya.Kulkarni@wdc.com>,
Martin Wilck <mwilck@suse.com>
Subject: [PATCH 21/35] nvme-cli: add "list.h"
Date: Tue, 26 Jan 2021 21:33:10 +0100 [thread overview]
Message-ID: <20210126203324.23610-22-mwilck@suse.com> (raw)
In-Reply-To: <20210126203324.23610-1-mwilck@suse.com>
From: Martin Wilck <mwilck@suse.com>
Adding "list.h" from multipath-tools, which got it from the kernel
long ago.
Signed-off-by: Martin Wilck <mwilck@suse.com>
---
list.h | 365 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 365 insertions(+)
create mode 100644 list.h
diff --git a/list.h b/list.h
new file mode 100644
index 0000000..ced021f
--- /dev/null
+++ b/list.h
@@ -0,0 +1,365 @@
+/*
+ * Copied from the Linux kernel source tree, version 2.6.0-test1.
+ *
+ * Licensed under the GPL v2 as per the whole kernel source tree.
+ *
+ */
+
+#ifndef _LIST_H
+#define _LIST_H
+
+#include <stddef.h>
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of_const(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (const type *)( (const char *)__mptr - offsetof(type,member) );})
+
+#define container_of(ptr, type, member) ({ \
+ typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+/*
+ * These are non-NULL pointers that will result in page faults
+ * under normal circumstances, used to verify that nobody uses
+ * non-initialized list entries.
+ */
+#define LIST_POISON1 ((void *) 0x00100100)
+#define LIST_POISON2 ((void *) 0x00200200)
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+#define INIT_LIST_HEAD(ptr) do { \
+ (ptr)->next = (ptr); (ptr)->prev = (ptr); \
+} while (0)
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * 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.
+ */
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = LIST_POISON1;
+ entry->prev = LIST_POISON2;
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(struct list_head *head)
+{
+ return head->next == head;
+}
+
+static inline void __list_splice(const struct list_head *list,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+
+ first->prev = prev;
+ prev->next = first;
+
+ last->next = next;
+ next->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+ if (!list_empty(list))
+ __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);
+}
+
+/**
+ * list_splice_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.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __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);
+ }
+}
+
+/**
+ * list_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 name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); \
+ pos = pos->next)
+
+/**
+ * __list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev; pos != (head); pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop counter.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*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 counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_reverse_safe - iterate backwards over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member), \
+ n = list_entry(pos->member.prev, typeof(*pos), member);\
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+/**
+ * list_for_some_entry_safe - iterate list from the given begin node to the given end node safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @from: the begin node of the iteration.
+ * @to: the end node of the iteration.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_some_entry_safe(pos, n, from, to, member) \
+ for (pos = list_entry((from)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (to); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_some_entry_reverse_safe - iterate backwards list from the given begin node to the given end node safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @from: the begin node of the iteration.
+ * @to: the end node of the iteration.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_some_entry_reverse_safe(pos, n, from, to, member) \
+ for (pos = list_entry((from)->prev, typeof(*pos), member), \
+ n = list_entry(pos->member.prev, typeof(*pos), member); \
+ &pos->member != (to); \
+ pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+#endif /* _LIST_H */
--
2.29.2
_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
next prev parent reply other threads:[~2021-01-26 20:35 UTC|newest]
Thread overview: 89+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-26 20:32 [PATCH 00/35] RFC: add "nvme monitor" subcommand mwilck
2021-01-26 20:32 ` [PATCH 01/35] nvme-monitor: add new stub mwilck
2021-01-26 20:32 ` [PATCH 02/35] monitor: create udev socket mwilck
2021-01-26 20:32 ` [PATCH 03/35] monitor: initialize signal handling mwilck
2021-01-26 20:32 ` [PATCH 04/35] monitor: add main loop for uevent monitoring mwilck
2021-01-26 20:32 ` [PATCH 05/35] monitor: add uevent filters mwilck
2021-02-04 6:58 ` Hannes Reinecke
2021-01-26 20:32 ` [PATCH 06/35] monitor: Create a log() macro mwilck
2021-02-04 7:01 ` Hannes Reinecke
2021-02-04 9:14 ` Martin Wilck
2021-01-26 20:32 ` [PATCH 07/35] fabrics: use " mwilck
2021-02-04 7:02 ` Hannes Reinecke
2021-01-26 20:32 ` [PATCH 08/35] monitor: add command line options to control logging mwilck
2021-02-04 7:04 ` Hannes Reinecke
2021-02-04 9:18 ` Martin Wilck
2021-01-26 20:32 ` [PATCH 09/35] nvme_get_ctrl_attr(): constify "path" argument mwilck
2021-02-04 7:05 ` Hannes Reinecke
2021-01-26 20:32 ` [PATCH 10/35] fabrics: export do_discover(), build_options() and config mwilck
2021-02-04 7:09 ` Hannes Reinecke
2021-02-04 9:21 ` Martin Wilck
2021-01-26 20:33 ` [PATCH 11/35] monitor: add option -A / --autoconnect mwilck
2021-01-29 18:59 ` Sagi Grimberg
2021-01-29 19:33 ` Martin Wilck
2021-01-29 20:09 ` Sagi Grimberg
2021-02-04 7:13 ` Hannes Reinecke
2021-01-26 20:33 ` [PATCH 12/35] monitor: add helpers for __attribute__((cleanup)) mwilck
2021-02-04 7:14 ` Hannes Reinecke
2021-01-26 20:33 ` [PATCH 13/35] monitor: disable nvmf-autoconnect udev rules in autoconnect mode mwilck
2021-01-29 1:52 ` Sagi Grimberg
2021-01-29 14:16 ` Martin Wilck
2021-01-29 18:54 ` Sagi Grimberg
2021-02-04 7:16 ` Hannes Reinecke
2021-02-04 9:37 ` Martin Wilck
2021-01-26 20:33 ` [PATCH 14/35] monitor: implement handling of fc_udev_device mwilck
2021-01-26 20:33 ` [PATCH 15/35] monitor: implement handling of nvme AEN events mwilck
2021-01-26 20:33 ` [PATCH 16/35] monitor: reset children's signal disposition mwilck
2021-01-29 1:54 ` Sagi Grimberg
2021-01-29 14:18 ` Martin Wilck
2021-01-26 20:33 ` [PATCH 17/35] monitor: handle SIGCHLD for terminated child processes mwilck
2021-01-29 1:54 ` Sagi Grimberg
2021-01-26 20:33 ` [PATCH 18/35] monitor: add "--persistent/-p" flag mwilck
2021-01-29 19:02 ` Sagi Grimberg
2021-01-29 19:45 ` Martin Wilck
2021-01-26 20:33 ` [PATCH 19/35] fabrics: use "const char *" in struct config mwilck
2021-02-04 7:20 ` Hannes Reinecke
2021-01-26 20:33 ` [PATCH 20/35] fabrics: export arg_str(), parse_conn_arg(), and remove_ctrl() mwilck
2021-01-26 20:33 ` mwilck [this message]
2021-01-26 20:33 ` [PATCH 22/35] conn-db: add simple connection registry mwilck
2021-01-29 1:59 ` Sagi Grimberg
2021-01-29 14:18 ` Martin Wilck
2021-01-26 20:33 ` [PATCH 23/35] monitor: handle restart of pending discoveries mwilck
2021-01-26 20:33 ` [PATCH 24/35] monitor: monitor_discovery(): try to reuse existing controllers mwilck
2021-01-26 20:33 ` [PATCH 25/35] monitor: read existing connections on startup mwilck
2021-01-26 20:33 ` [PATCH 26/35] monitor: implement starting discovery controllers " mwilck
2021-01-29 21:06 ` Sagi Grimberg
2021-01-29 21:13 ` Martin Wilck
2021-01-29 21:18 ` Sagi Grimberg
2021-01-26 20:33 ` [PATCH 27/35] monitor: implement cleanup of created discovery controllers mwilck
2021-01-26 20:33 ` [PATCH 28/35] monitor: basic handling of add/remove uevents for nvme controllers mwilck
2021-01-26 20:33 ` [PATCH 29/35] monitor: kill running discovery tasks on exit mwilck
2021-01-26 20:33 ` [PATCH 30/35] monitor: add connection property options from connect-all mwilck
2021-01-26 20:33 ` [PATCH 31/35] completions: add completions for nvme monitor mwilck
2021-01-26 20:33 ` [PATCH 32/35] nvmf-autoconnect: add unit file for nvme-monitor.service mwilck
2021-01-29 19:08 ` Sagi Grimberg
2021-01-29 19:50 ` Martin Wilck
2021-01-26 20:33 ` [PATCH 33/35] nvme-connect-all(1): fix documentation for --quiet/-S mwilck
2021-01-29 19:09 ` Sagi Grimberg
2021-01-26 20:33 ` [PATCH 34/35] nvme-monitor(1): add man page for nvme-monitor mwilck
2021-01-26 20:33 ` [PATCH 35/35] monitor: add option --keep/-K mwilck
2021-01-29 19:10 ` Sagi Grimberg
2021-01-29 19:53 ` Martin Wilck
2021-01-29 20:16 ` Sagi Grimberg
2021-01-29 20:30 ` Martin Wilck
2021-01-29 20:45 ` Sagi Grimberg
2021-01-29 20:51 ` Martin Wilck
2021-01-29 20:57 ` Sagi Grimberg
2021-01-29 21:05 ` Martin Wilck
2021-01-29 21:11 ` Sagi Grimberg
2021-01-29 21:15 ` Martin Wilck
2021-01-29 21:21 ` Sagi Grimberg
2021-02-04 7:34 ` Hannes Reinecke
2021-02-04 9:41 ` Martin Wilck
2021-01-29 1:14 ` [PATCH 00/35] RFC: add "nvme monitor" subcommand Sagi Grimberg
2021-01-29 11:18 ` Martin Wilck
2021-01-29 20:08 ` Sagi Grimberg
2021-01-29 20:27 ` Martin Wilck
2021-02-04 7:52 ` Hannes Reinecke
2021-02-22 19:02 ` Enzo Matsumiya
2021-02-22 21:05 ` Martin Wilck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210126203324.23610-22-mwilck@suse.com \
--to=mwilck@suse.com \
--cc=Chaitanya.Kulkarni@wdc.com \
--cc=hare@suse.de \
--cc=kbusch@kernel.org \
--cc=linux-nvme@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox