[sheepdog] [RFC PATCH 3/3] make list more typesafe
MORITA Kazutaka
morita.kazutaka at gmail.com
Wed Sep 25 20:12:11 CEST 2013
From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
This patch adds more strict type checking to list functions and
forbids inserting invalid list nodes into the list head.
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
dog/trace.c | 7 +-
dog/treeview.c | 27 ++++---
include/list.h | 167 +++++++++++++++++++++++++++---------------
include/work.h | 4 +-
lib/logger.c | 11 +--
lib/util.c | 10 +--
lib/work.c | 28 +++----
sheep/cluster.h | 7 +-
sheep/cluster/corosync.c | 32 ++++----
sheep/cluster/shepherd.c | 22 +++---
sheep/cluster/zookeeper.c | 17 +++--
sheep/group.c | 42 +++++------
sheep/object_cache.c | 28 +++----
sheep/ops.c | 2 +-
sheep/request.c | 41 ++++++-----
sheep/sheep.c | 2 +-
sheep/sheep_priv.h | 41 ++++++-----
sheep/store.c | 2 +-
sheep/trace/trace.c | 17 +++--
sheep/vdi.c | 12 +--
shepherd/shepherd.c | 35 ++++-----
tests/unit/sheep/mock_sheep.c | 2 +-
22 files changed, 308 insertions(+), 248 deletions(-)
diff --git a/dog/trace.c b/dog/trace.c
index 9346849..302ee34 100644
--- a/dog/trace.c
+++ b/dog/trace.c
@@ -252,7 +252,8 @@ struct graph_stat_entry {
uint16_t nr_calls;
};
-static LIST_HEAD(stat_list);
+static LIST_HEAD(list_stat_head, struct graph_stat_entry, list) stat_list =
+ LIST_HEAD_INITIALIZER(stat_list);
static int graph_stat_cmp(const struct graph_stat_entry *a,
const struct graph_stat_entry *b)
@@ -290,14 +291,14 @@ static void prepare_stat_tree(struct trace_graph_item *item)
free(new);
return;
}
- list_add(&new->list, &stat_list);
+ list_add(new, &stat_list);
}
static void stat_list_print(void)
{
struct graph_stat_entry *entry;
- list_for_each_entry(entry, &stat_list, list) {
+ list_for_each_entry(entry, &stat_list) {
float total = (float)entry->duration / 1000000000;
float per = (float)entry->duration / entry->nr_calls / 1000000;
diff --git a/dog/treeview.c b/dog/treeview.c
index c407f2d..68a2917 100644
--- a/dog/treeview.c
+++ b/dog/treeview.c
@@ -26,10 +26,12 @@ struct vdi_tree {
uint32_t vid;
uint32_t pvid;
bool highlight;
- struct list_head children;
+ struct list_tree_head *children;
struct list_node siblings;
};
+LIST_HEAD(list_tree_head, struct vdi_tree, siblings);
+
static int *width, *more;
static struct vdi_tree *root;
@@ -38,7 +40,7 @@ static struct vdi_tree *find_vdi(struct vdi_tree *parent, uint32_t vid,
{
struct vdi_tree *vdi, *ret;
- list_for_each_entry(vdi, &parent->children, siblings) {
+ list_for_each_entry(vdi, parent->children) {
if (vdi->vid == vid && !strcmp(vdi->name, name))
return vdi;
@@ -60,7 +62,8 @@ static struct vdi_tree *new_vdi(const char *name, const char *label,
vdi->vid = vid;
vdi->pvid = pvid;
vdi->highlight = highlight;
- INIT_LIST_HEAD(&vdi->children);
+ vdi->children = xmalloc(sizeof(*vdi->children));
+ INIT_LIST_HEAD(vdi->children);
return vdi;
}
@@ -82,17 +85,17 @@ void add_vdi_tree(const char *name, const char *label, uint32_t vid,
if (!parent)
parent = root;
- list_add_tail(&vdi->siblings, &parent->children);
+ list_add_tail(vdi, parent->children);
}
static void compaction(struct vdi_tree *parent)
{
struct vdi_tree *vdi, *new_parent;
- list_for_each_entry(vdi, &parent->children, siblings) {
+ list_for_each_entry(vdi, parent->children) {
new_parent = find_vdi(root, vdi->pvid, vdi->name);
if (new_parent && parent != new_parent)
- list_move_tail(&vdi->siblings, &new_parent->children);
+ list_move_tail(vdi, new_parent->children);
compaction(vdi);
}
@@ -103,7 +106,7 @@ static int get_depth(struct vdi_tree *parent)
struct vdi_tree *vdi;
int max_depth = 0, depth;
- list_for_each_entry(vdi, &parent->children, siblings) {
+ list_for_each_entry(vdi, parent->children) {
depth = get_depth(vdi);
if (max_depth < depth)
max_depth = depth;
@@ -148,7 +151,7 @@ static void _dump_tree(struct vdi_tree *current, int level, bool first, bool las
if (current->highlight)
printf(TEXT_NORMAL);
- if (list_empty(¤t->children)) {
+ if (list_empty(current->children)) {
putchar('\n');
return;
}
@@ -156,10 +159,10 @@ static void _dump_tree(struct vdi_tree *current, int level, bool first, bool las
more[level] = !last;
width[level] = strlen(current->label);
- list_for_each_entry(vdi, ¤t->children, siblings) {
+ list_for_each_entry(vdi, current->children) {
_dump_tree(vdi, level + 1,
- &vdi->siblings == current->children.n.next,
- vdi->siblings.next == ¤t->children.n);
+ &vdi->siblings == current->children->h.n.next,
+ vdi->siblings.next == ¤t->children->h.n);
}
}
@@ -179,7 +182,7 @@ void dump_tree(void)
return;
}
- list_for_each_entry(vdi, &root->children, siblings) {
+ list_for_each_entry(vdi, root->children) {
printf("%s", vdi->name);
more[0] = 0;
width[0] = strlen(vdi->name);
diff --git a/include/list.h b/include/list.h
index 03250ae..fd58627 100644
--- a/include/list.h
+++ b/include/list.h
@@ -12,60 +12,75 @@ struct list_node {
struct list_node *prev;
};
-struct list_head {
+struct __list_head {
struct list_node n;
};
-#define LIST_HEAD_INIT(name) { { &(name.n), &(name.n) } }
-#define LIST_NODE_INIT { NULL, NULL }
+#define LIST_HEAD_INITIALIZER(name) { .h.n = { &((name).h.n), &((name).h.n) } }
+#define LIST_NODE_INITIALIZER { NULL, NULL }
-#define LIST_HEAD(name) \
- struct list_head name = LIST_HEAD_INIT(name)
-#define LIST_NODE(name) \
- struct list_node name = LIST_NODE_INIT
+#define LIST_HEAD(name, type, member) \
+struct name { \
+ struct __list_head h; \
+ \
+ /* The below fields are used only at compile time */ \
+ type *t; \
+ char o[offsetof(type, member)]; \
+}
-static inline void INIT_LIST_HEAD(struct list_head *list)
+static inline void __INIT_LIST_HEAD(struct __list_head *list)
{
list->n.next = &list->n;
list->n.prev = &list->n;
}
+#define INIT_LIST_HEAD(head) __INIT_LIST_HEAD(&(head)->h)
+
static inline void INIT_LIST_NODE(struct list_node *list)
{
list->next = NULL;
list->prev = NULL;
}
-#define list_first_entry(head, type, member) \
- list_entry((head)->n.next, type, member)
+#define list_first_entry(head) \
+ list_entry((head)->h.n.next, head)
+
+#define list_next_entry(node, head) \
+ list_entry(list_node_of(node, head)->next, head)
-static inline bool list_empty(const struct list_head *head)
+static inline bool __list_empty(struct __list_head *head)
{
return head->n.next == &head->n;
}
-#define list_entry(ptr, type, member) \
- container_of(ptr, type, member)
+#define list_empty(head) __list_empty(&(head)->h)
+
+#define list_type_check(entry, head) (void) ((entry) == (head)->t)
+
+#define list_entry(node, head) \
+ offset_container_of(node, typeof(*(head)->t), sizeof((head)->o))
+
+#define list_node_of(entry, head) \
+({ \
+ list_type_check(entry, head); \
+ offset_member_of(entry, struct list_node, sizeof((head)->o)); \
+})
#define list_for_each(pos, head) \
- for (typeof(pos) LOCAL(n) = (pos = (head)->n.next, pos->next); \
+ for (struct list_node *LOCAL(n) = (pos = (head)->n.next, \
+ pos->next); \
pos != &(head)->n; \
pos = LOCAL(n), LOCAL(n) = pos->next)
-#define list_for_each_entry(pos, head, member) \
- for (typeof(pos) LOCAL(n) = (pos = list_entry((head)->n.next, \
- typeof(*pos), \
- member), \
- list_entry(pos->member.next, \
- typeof(*pos), \
- member)); \
- &pos->member != &(head)->n; \
- pos = LOCAL(n), LOCAL(n) = list_entry(LOCAL(n)->member.next, \
- typeof(*LOCAL(n)), \
- member))
+#define list_for_each_entry(pos, head) \
+ for (typeof(pos) LOCAL(n) = (pos = list_entry((head)->h.n.next, \
+ head), \
+ list_next_entry(pos, head)); \
+ list_node_of(pos, head) != &(head)->h.n; \
+ pos = LOCAL(n), LOCAL(n) = list_next_entry(LOCAL(n), head))
-static inline bool __list_linked(const struct list_node *node,
- const struct list_head *head)
+static inline bool ____list_linked(const struct list_node *node,
+ const struct __list_head *head)
{
struct list_node *pos;
@@ -77,19 +92,22 @@ static inline bool __list_linked(const struct list_node *node,
return false;
}
-static inline bool list_linked(const struct list_node *node,
- const struct list_head *head)
+static inline bool __list_linked(const struct list_node *node,
+ const struct __list_head *head)
{
bool ret = (node->next != NULL);
- assert(ret == __list_linked(node, head));
+ assert(ret == ____list_linked(node, head));
return ret;
}
-static inline void __list_add(struct list_node *new,
- struct list_node *prev,
- struct list_node *next)
+#define list_linked(entry, head) \
+ __list_linked(list_node_of(entry, head), &(head)->h)
+
+static inline void ____list_add(struct list_node *new,
+ struct list_node *prev,
+ struct list_node *next)
{
next->prev = new;
new->next = next;
@@ -97,17 +115,24 @@ static inline void __list_add(struct list_node *new,
prev->next = new;
}
-static inline void list_add(struct list_node *new, struct list_head *head)
+static inline void __list_add(struct list_node *new, struct __list_head *head)
{
- __list_add(new, &head->n, head->n.next);
+ ____list_add(new, &head->n, head->n.next);
}
-static inline void list_add_tail(struct list_node *new, struct list_head *head)
+#define list_add(new, head) \
+ __list_add(list_node_of(new, head), &(head)->h)
+
+static inline void __list_add_tail(struct list_node *new,
+ struct __list_head *head)
{
- __list_add(new, head->n.prev, &head->n);
+ ____list_add(new, head->n.prev, &head->n);
}
-static inline void __list_del(struct list_node *prev, struct list_node *next)
+#define list_add_tail(new, head) \
+ __list_add_tail(list_node_of(new, head), &(head)->h)
+
+static inline void ____list_del(struct list_node *prev, struct list_node *next)
{
next->prev = prev;
prev->next = next;
@@ -115,31 +140,40 @@ static inline void __list_del(struct list_node *prev, struct list_node *next)
static inline void __list_del_entry(struct list_node *entry)
{
- __list_del(entry->prev, entry->next);
+ ____list_del(entry->prev, entry->next);
}
-static inline void list_del(struct list_node *entry,
- const struct list_head *head)
+static inline void __list_del(struct list_node *entry,
+ const struct __list_head *head)
{
assert(__list_linked(entry, head));
- __list_del(entry->prev, entry->next);
+ ____list_del(entry->prev, entry->next);
entry->next = entry->prev = NULL;
}
-static inline void list_move(struct list_node *list, struct list_head *head)
+#define list_del(entry, head) \
+ __list_del(list_node_of(entry, head), &(head)->h)
+
+static inline void __list_move(struct list_node *list, struct __list_head *head)
{
__list_del_entry(list);
- list_add(list, head);
+ __list_add(list, head);
}
-static inline void list_move_tail(struct list_node *list,
- struct list_head *head)
+#define list_move(entry, head) \
+ __list_move(list_node_of(entry, head), &(head)->h)
+
+static inline void __list_move_tail(struct list_node *list,
+ struct __list_head *head)
{
__list_del_entry(list);
- list_add_tail(list, head);
+ __list_add_tail(list, head);
}
-static inline void __list_splice(const struct list_head *list,
+#define list_move_tail(entry, head) \
+ __list_move_tail(list_node_of(entry, head), &(head)->h)
+
+static inline void __list_splice(const struct __list_head *list,
struct list_node *prev,
struct list_node *next)
{
@@ -153,24 +187,36 @@ static inline void __list_splice(const struct list_head *list,
next->prev = last;
}
-static inline void list_splice_init(struct list_head *list,
- struct list_head *head)
+static inline void __list_splice_init(struct __list_head *list,
+ struct __list_head *head)
{
- if (!list_empty(list)) {
+ if (!__list_empty(list)) {
__list_splice(list, &head->n, head->n.next);
- INIT_LIST_HEAD(list);
+ __INIT_LIST_HEAD(list);
}
}
-static inline void list_splice_tail_init(struct list_head *list,
- struct list_head *head)
+#define list_splice_init(list, head) \
+({ \
+ (void) ((list) == (head)); \
+ __list_splice_init(&(list)->h, &(head)->h); \
+})
+
+static inline void __list_splice_tail_init(struct __list_head *list,
+ struct __list_head *head)
{
- if (!list_empty(list)) {
+ if (!__list_empty(list)) {
__list_splice(list, head->n.prev, &head->n);
- INIT_LIST_HEAD(list);
+ __INIT_LIST_HEAD(list);
}
}
+#define list_splice_tail_init(list, head) \
+({ \
+ (void) ((list) == (head)); \
+ __list_splice_tail_init(&(list)->h, &(head)->h); \
+})
+
/* hlist, mostly useful for hash tables */
#define LIST_POISON1 ((void *) 0x00100100)
@@ -270,7 +316,10 @@ static inline void hlist_add_after(struct hlist_node *n,
(tpos = hlist_entry(pos, typeof(*tpos), member), 1); \
pos = LOCAL(n))
-void list_sort(void *priv, struct list_head *head,
- int (*cmp)(void *priv, struct list_node *a,
- struct list_node *b));
+void __list_sort(void *priv, struct __list_head *head,
+ int (*cmp)(void *priv, struct list_node *a,
+ struct list_node *b));
+
+#define list_sort(priv, head, cmp) __list_sort(priv, &(head)->h, cmp)
+
#endif /* __LIST_H__ */
diff --git a/include/work.h b/include/work.h
index 322b930..5595d2b 100644
--- a/include/work.h
+++ b/include/work.h
@@ -16,9 +16,11 @@ struct work {
work_func_t done;
};
+LIST_HEAD(list_work_head, struct work, w_list);
+
struct work_queue {
int wq_state;
- struct list_head pending_list;
+ struct list_work_head pending_list;
};
enum wq_thread_control {
diff --git a/lib/logger.c b/lib/logger.c
index 5a75498..92f4bc8 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -104,7 +104,8 @@ struct log_format {
struct list_node list;
};
-static LIST_HEAD(log_formats);
+static LIST_HEAD(, struct log_format, list) log_formats =
+ LIST_HEAD_INITIALIZER(log_formats);
static struct log_format *format;
static int log_fd = -1;
@@ -225,7 +226,7 @@ static void log_format_register(const char *name, formatter_fn formatter)
f->name = name;
f->formatter = formatter;
- list_add(&f->list, &log_formats);
+ list_add(f, &log_formats);
}
/*
@@ -241,7 +242,7 @@ init_log_formatter(void)
log_format_register("server", server_log_formatter);
log_format_register("default", default_log_formatter);
- list_for_each_entry(f, &log_formats, list) {
+ list_for_each_entry(f, &log_formats) {
if (!strcmp(f->name, "default")) {
format = f;
return;
@@ -580,7 +581,7 @@ void early_log_init(const char *format_name, struct logger_user_info *user_info)
logger_user_info = user_info;
- list_for_each_entry(f, &log_formats, list) {
+ list_for_each_entry(f, &log_formats) {
if (!strcmp(f->name, format_name)) {
format = f;
return;
@@ -589,7 +590,7 @@ void early_log_init(const char *format_name, struct logger_user_info *user_info)
sd_err("invalid log format: %s", format_name);
sd_err("valid options are:");
- list_for_each_entry(f, &log_formats, list) {
+ list_for_each_entry(f, &log_formats) {
sd_err("\t%s", f->name);
}
diff --git a/lib/util.c b/lib/util.c
index bde6833..1d50a50 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -659,7 +659,7 @@ static void
merge_and_restore_back_links(void *priv,
int (*cmp)(void *priv, struct list_node *a,
struct list_node *b),
- struct list_head *head,
+ struct __list_head *head,
struct list_node *a, struct list_node *b)
{
struct list_node *tail = &head->n;
@@ -710,9 +710,9 @@ merge_and_restore_back_links(void *priv,
* @b. If @a and @b are equivalent, and their original relative
* ordering is to be preserved, @cmp must return 0.
*/
-void list_sort(void *priv, struct list_head *head,
- int (*cmp)(void *priv, struct list_node *a,
- struct list_node *b))
+void __list_sort(void *priv, struct __list_head *head,
+ int (*cmp)(void *priv, struct list_node *a,
+ struct list_node *b))
{
/* sorted partial lists -- last slot is a sentinel */
#define MAX_LIST_LENGTH_BITS 20
@@ -721,7 +721,7 @@ void list_sort(void *priv, struct list_head *head,
int max_lev = 0;
struct list_node *list;
- if (list_empty(head))
+ if (__list_empty(head))
return;
memset(part, 0, sizeof(part));
diff --git a/lib/work.c b/lib/work.c
index f88056e..941b3cd 100644
--- a/lib/work.c
+++ b/lib/work.c
@@ -51,7 +51,7 @@ static void (*suspend_callback)(void);
struct worker_info {
const char *name;
- struct list_head finished_list;
+ struct list_work_head finished_list;
struct list_node worker_info_siblings;
pthread_mutex_t finished_lock;
@@ -74,7 +74,8 @@ struct worker_info {
};
static int efd;
-static LIST_HEAD(worker_info_list);
+static LIST_HEAD(, struct worker_info, worker_info_siblings) worker_info_list =
+ LIST_HEAD_INITIALIZER(worker_info_list);
static size_t nr_nodes = 1;
static size_t (*wq_get_nr_nodes)(void);
@@ -161,7 +162,7 @@ void suspend_worker_threads(void)
struct worker_info *wi;
int tid;
- list_for_each_entry(wi, &worker_info_list, worker_info_siblings) {
+ list_for_each_entry(wi, &worker_info_list) {
pthread_mutex_lock(&wi->pending_lock);
}
@@ -199,7 +200,7 @@ void resume_worker_threads(void)
for (int i = 0; i < nr_threads; i++)
eventfd_xread(ack_efd);
- list_for_each_entry(wi, &worker_info_list, worker_info_siblings) {
+ list_for_each_entry(wi, &worker_info_list) {
pthread_mutex_unlock(&wi->pending_lock);
}
}
@@ -225,7 +226,7 @@ void queue_work(struct work_queue *q, struct work *work)
/* double the thread pool size */
create_worker_threads(wi, wi->nr_threads * 2);
- list_add_tail(&work->w_list, &wi->q.pending_list);
+ list_add_tail(work, &wi->q.pending_list);
pthread_mutex_unlock(&wi->pending_lock);
pthread_cond_signal(&wi->pending_cond);
@@ -235,21 +236,21 @@ static void worker_thread_request_done(int fd, int events, void *data)
{
struct worker_info *wi;
struct work *work;
- LIST_HEAD(list);
+ struct list_work_head list = LIST_HEAD_INITIALIZER(list);
if (wq_get_nr_nodes)
nr_nodes = wq_get_nr_nodes();
eventfd_xread(fd);
- list_for_each_entry(wi, &worker_info_list, worker_info_siblings) {
+ list_for_each_entry(wi, &worker_info_list) {
pthread_mutex_lock(&wi->finished_lock);
list_splice_init(&wi->finished_list, &list);
pthread_mutex_unlock(&wi->finished_lock);
while (!list_empty(&list)) {
- work = list_first_entry(&list, struct work, w_list);
- list_del(&work->w_list, &list);
+ work = list_first_entry(&list);
+ list_del(work, &list);
work->done(work);
uatomic_dec(&wi->nr_workers);
@@ -300,17 +301,16 @@ retest:
goto retest;
}
- work = list_first_entry(&wi->q.pending_list,
- struct work, w_list);
+ work = list_first_entry(&wi->q.pending_list);
- list_del(&work->w_list, &wi->q.pending_list);
+ list_del(work, &wi->q.pending_list);
pthread_mutex_unlock(&wi->pending_lock);
if (work->fn)
work->fn(work);
pthread_mutex_lock(&wi->finished_lock);
- list_add_tail(&work->w_list, &wi->finished_list);
+ list_add_tail(work, &wi->finished_list);
pthread_mutex_unlock(&wi->finished_lock);
eventfd_xwrite(efd, 1);
@@ -403,7 +403,7 @@ struct work_queue *create_work_queue(const char *name,
if (ret < 0)
goto destroy_threads;
- list_add(&wi->worker_info_siblings, &worker_info_list);
+ list_add(wi, &worker_info_list);
return &wi->q;
destroy_threads:
diff --git a/sheep/cluster.h b/sheep/cluster.h
index 6a60033..b2019fa 100644
--- a/sheep/cluster.h
+++ b/sheep/cluster.h
@@ -115,7 +115,8 @@ struct cluster_driver {
struct list_node list;
};
-extern struct list_head cluster_drivers;
+LIST_HEAD(list_cdrv_head, struct cluster_driver, list);
+extern struct list_cdrv_head cluster_drivers;
#ifdef HAVE_COROSYNC
#define DEFAULT_CLUSTER_DRIVER "corosync"
@@ -128,11 +129,11 @@ static void __attribute__((constructor)) regist_ ## driver(void) \
{ \
if (!driver.init || !driver.join || !driver.leave || !driver.notify) \
panic("the driver '%s' is incomplete", driver.name); \
- list_add(&driver.list, &cluster_drivers); \
+ list_add(&driver, &cluster_drivers); \
}
#define FOR_EACH_CLUSTER_DRIVER(driver) \
- list_for_each_entry(driver, &cluster_drivers, list)
+ list_for_each_entry(driver, &cluster_drivers)
static inline struct cluster_driver *find_cdrv(const char *name)
{
diff --git a/sheep/cluster/corosync.c b/sheep/cluster/corosync.c
index 7898c73..55657d7 100644
--- a/sheep/cluster/corosync.c
+++ b/sheep/cluster/corosync.c
@@ -34,9 +34,6 @@ static struct cpg_name cpg_group = { 8, "sheepdog" };
static corosync_cfg_handle_t cfg_handle;
static struct cpg_node this_node;
-static LIST_HEAD(corosync_block_event_list);
-static LIST_HEAD(corosync_nonblock_event_list);
-
static struct cpg_node cpg_nodes[COROSYNC_MAX_NODES];
static size_t nr_cpg_nodes;
static bool self_elect;
@@ -80,6 +77,11 @@ struct corosync_event {
struct list_node list;
};
+static LIST_HEAD(, struct corosync_event, list) corosync_block_event_list =
+ LIST_HEAD_INITIALIZER(corosync_block_event_list);
+static LIST_HEAD(, struct corosync_event, list) corosync_nonblock_event_list =
+ LIST_HEAD_INITIALIZER(corosync_nonblock_event_list);
+
struct corosync_message {
struct cpg_node sender;
enum corosync_message_type type:16;
@@ -206,7 +208,7 @@ find_block_event(enum corosync_event_type type, struct cpg_node *sender)
{
struct corosync_event *cevent;
- list_for_each_entry(cevent, &corosync_block_event_list, list) {
+ list_for_each_entry(cevent, &corosync_block_event_list) {
if (cevent->type == type &&
cpg_node_equal(&cevent->sender, sender))
return cevent;
@@ -220,7 +222,7 @@ find_nonblock_event(enum corosync_event_type type, struct cpg_node *sender)
{
struct corosync_event *cevent;
- list_for_each_entry(cevent, &corosync_nonblock_event_list, list) {
+ list_for_each_entry(cevent, &corosync_nonblock_event_list) {
if (cevent->type == type &&
cpg_node_equal(&cevent->sender, sender))
return cevent;
@@ -378,12 +380,10 @@ static void __corosync_dispatch(void)
!list_empty(&corosync_nonblock_event_list)) {
bool block;
if (!list_empty(&corosync_nonblock_event_list)) {
- cevent = list_first_entry(&corosync_nonblock_event_list,
- typeof(*cevent), list);
+ cevent = list_first_entry(&corosync_nonblock_event_list);
block = false;
} else {
- cevent = list_first_entry(&corosync_block_event_list,
- typeof(*cevent), list);
+ cevent = list_first_entry(&corosync_block_event_list);
block = true;
}
@@ -403,9 +403,9 @@ static void __corosync_dispatch(void)
}
if (block)
- list_del(&cevent->list, &corosync_block_event_list);
+ list_del(cevent, &corosync_block_event_list);
else
- list_del(&cevent->list, &corosync_nonblock_event_list);
+ list_del(cevent, &corosync_nonblock_event_list);
free(cevent->msg);
free(cevent);
}
@@ -439,9 +439,9 @@ update_event(enum corosync_event_type type, struct cpg_node *sender, void *msg,
static void queue_event(struct corosync_event *cevent)
{
if (cevent->type == COROSYNC_EVENT_TYPE_BLOCK)
- list_add_tail(&cevent->list, &corosync_block_event_list);
+ list_add_tail(cevent, &corosync_block_event_list);
else
- list_add_tail(&cevent->list, &corosync_nonblock_event_list);
+ list_add_tail(cevent, &corosync_nonblock_event_list);
}
static void cdrv_cpg_deliver(cpg_handle_t handle,
@@ -468,7 +468,7 @@ static void cdrv_cpg_deliver(cpg_handle_t handle,
cevent = update_event(COROSYNC_EVENT_TYPE_BLOCK, &cmsg->sender,
cmsg->msg, cmsg->msg_len);
if (cevent) {
- list_del(&cevent->list, &corosync_block_event_list);
+ list_del(cevent, &corosync_block_event_list);
free(cevent->msg);
free(cevent);
}
@@ -588,7 +588,7 @@ static void cdrv_cpg_confchg(cpg_handle_t handle,
cevent = find_event(COROSYNC_EVENT_TYPE_JOIN, left_sheep + i);
if (cevent) {
/* the node left before joining */
- list_del(&cevent->list, &corosync_nonblock_event_list);
+ list_del(cevent, &corosync_nonblock_event_list);
free(cevent->msg);
free(cevent);
continue;
@@ -597,7 +597,7 @@ static void cdrv_cpg_confchg(cpg_handle_t handle,
cevent = find_event(COROSYNC_EVENT_TYPE_BLOCK, left_sheep + i);
if (cevent) {
/* the node left before sending UNBLOCK */
- list_del(&cevent->list, &corosync_block_event_list);
+ list_del(cevent, &corosync_block_event_list);
free(cevent->msg);
free(cevent);
}
diff --git a/sheep/cluster/shepherd.c b/sheep/cluster/shepherd.c
index 494af01..e6bb9df 100644
--- a/sheep/cluster/shepherd.c
+++ b/sheep/cluster/shepherd.c
@@ -174,8 +174,10 @@ struct sph_event {
struct list_node event_list;
};
-static LIST_HEAD(nonblocked_event_list);
-static LIST_HEAD(blocked_event_list);
+static LIST_HEAD(, struct sph_event, event_list) nonblocked_event_list =
+ LIST_HEAD_INITIALIZER(nonblocked_event_list);
+static LIST_HEAD(, struct sph_event, event_list) blocked_event_list =
+ LIST_HEAD_INITIALIZER(blocked_event_list);
static int sph_event_fd;
@@ -185,12 +187,10 @@ static bool sph_process_event(void)
bool nonblock;
if (!list_empty(&nonblocked_event_list)) {
- ev = list_first_entry(&nonblocked_event_list,
- struct sph_event, event_list);
+ ev = list_first_entry(&nonblocked_event_list);
nonblock = true;
} else if (!list_empty(&blocked_event_list)) {
- ev = list_first_entry(&blocked_event_list,
- struct sph_event, event_list);
+ ev = list_first_entry(&blocked_event_list);
nonblock = false;
} else
return false;
@@ -214,9 +214,9 @@ static bool sph_process_event(void)
remove:
if (nonblock)
- list_del(&ev->event_list, &nonblocked_event_list);
+ list_del(ev, &nonblocked_event_list);
else
- list_del(&ev->event_list, &blocked_event_list);
+ list_del(ev, &blocked_event_list);
free(ev->msg);
free(ev);
@@ -244,9 +244,9 @@ static void push_sph_event(bool nonblock, struct sd_node *sender,
ev->callbacked = false;
if (nonblock)
- list_add_tail(&ev->event_list, &nonblocked_event_list);
+ list_add_tail(ev, &nonblocked_event_list);
else
- list_add_tail(&ev->event_list, &blocked_event_list);
+ list_add_tail(ev, &blocked_event_list);
eventfd_xwrite(sph_event_fd, 1);
}
@@ -260,7 +260,7 @@ static void remove_one_block_event(void)
/* FIXME: should I treat this case as an error? */
return;
- list_for_each_entry(ev, &blocked_event_list, event_list) {
+ list_for_each_entry(ev, &blocked_event_list) {
if (ev->removed)
continue;
diff --git a/sheep/cluster/zookeeper.c b/sheep/cluster/zookeeper.c
index 18c7ef4..e221c6e 100644
--- a/sheep/cluster/zookeeper.c
+++ b/sheep/cluster/zookeeper.c
@@ -73,7 +73,8 @@ static struct rb_node_root sd_node_root = RB_ROOT_INITIALIZER(node_cmp);
static size_t nr_sd_nodes;
static struct sd_lock zk_tree_lock = SD_LOCK_INITIALIZER;
static struct sd_lock zk_compete_master_lock = SD_LOCK_INITIALIZER;
-static LIST_HEAD(zk_block_list);
+static LIST_HEAD(, struct zk_node, list) zk_block_list =
+ LIST_HEAD_INITIALIZER(zk_block_list);
static uatomic_bool is_master;
static uatomic_bool stop;
static bool joined;
@@ -891,7 +892,7 @@ static void kick_block_event(void)
if (list_empty(&zk_block_list))
return;
- block = list_first_entry(&zk_block_list, typeof(*block), list);
+ block = list_first_entry(&zk_block_list);
if (!block->callbacked)
block->callbacked = sd_block_handler(&block->node);
}
@@ -900,9 +901,9 @@ static void block_event_list_del(struct zk_node *n)
{
struct zk_node *ev;
- list_for_each_entry(ev, &zk_block_list, list) {
+ list_for_each_entry(ev, &zk_block_list) {
if (node_eq(&ev->node, &n->node)) {
- list_del(&ev->list, &zk_block_list);
+ list_del(ev, &zk_block_list);
free(ev);
}
}
@@ -929,8 +930,8 @@ static void zk_handle_block(struct zk_event *ev)
sd_debug("BLOCK");
block->node = ev->sender.node;
- list_add_tail(&block->list, &zk_block_list);
- block = list_first_entry(&zk_block_list, typeof(*block), list);
+ list_add_tail(block, &zk_block_list);
+ block = list_first_entry(&zk_block_list);
if (!block->callbacked)
block->callbacked = sd_block_handler(&block->node);
}
@@ -942,10 +943,10 @@ static void zk_handle_unblock(struct zk_event *ev)
sd_debug("UNBLOCK");
if (list_empty(&zk_block_list))
return;
- block = list_first_entry(&zk_block_list, typeof(*block), list);
+ block = list_first_entry(&zk_block_list);
sd_notify_handler(&ev->sender.node, ev->buf, ev->buf_len);
- list_del(&block->list, &zk_block_list);
+ list_del(block, &zk_block_list);
free(block);
}
diff --git a/sheep/group.c b/sheep/group.c
index 88afc45..5fdd220 100644
--- a/sheep/group.c
+++ b/sheep/group.c
@@ -27,9 +27,11 @@ static pthread_mutex_t wait_vdis_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t wait_vdis_cond = PTHREAD_COND_INITIALIZER;
static refcnt_t nr_get_vdis_works;
+LIST_HEAD(list_pending_head, struct request, pending_list);
+
static main_thread(struct vnode_info *) current_vnode_info;
-static main_thread(struct list_head *) pending_block_list;
-static main_thread(struct list_head *) pending_notify_list;
+static main_thread(struct list_pending_head *) pending_block_list;
+static main_thread(struct list_pending_head *) pending_notify_list;
static int get_zones_nr_from(struct rb_node_root *nroot)
{
@@ -248,7 +250,7 @@ static void cluster_op_done(struct work *work)
req->status = REQUEST_DONE;
return;
drop:
- list_del(&req->pending_list, main_thread_get(pending_block_list));
+ list_del(req, main_thread_get(pending_block_list));
req->rp.result = SD_RES_CLUSTER_ERROR;
put_request(req);
cluster_op_running = false;
@@ -275,8 +277,7 @@ main_fn bool sd_block_handler(const struct sd_node *sender)
cluster_op_running = true;
- req = list_first_entry(main_thread_get(pending_block_list),
- struct request, pending_list);
+ req = list_first_entry(main_thread_get(pending_block_list));
req->work.fn = do_process_work;
req->work.done = cluster_op_done;
@@ -304,8 +305,7 @@ main_fn void queue_cluster_request(struct request *req)
sd_strerror(ret));
goto error;
}
- list_add_tail(&req->pending_list,
- main_thread_get(pending_block_list));
+ list_add_tail(req, main_thread_get(pending_block_list));
} else {
struct vdi_op_message *msg;
size_t size;
@@ -320,8 +320,7 @@ main_fn void queue_cluster_request(struct request *req)
goto error;
}
- list_add_tail(&req->pending_list,
- main_thread_get(pending_notify_list));
+ list_add_tail(req, main_thread_get(pending_notify_list));
free(msg);
}
@@ -701,16 +700,12 @@ main_fn void sd_notify_handler(const struct sd_node *sender, void *data,
if (node_is_local(sender)) {
if (has_process_work(op)) {
req = list_first_entry(
- main_thread_get(pending_block_list),
- struct request, pending_list);
- list_del(&req->pending_list,
- main_thread_get(pending_block_list));
+ main_thread_get(pending_block_list));
+ list_del(req, main_thread_get(pending_block_list));
} else {
req = list_first_entry(
- main_thread_get(pending_notify_list),
- struct request, pending_list);
- list_del(&req->pending_list,
- main_thread_get(pending_notify_list));
+ main_thread_get(pending_notify_list));
+ list_del(req, main_thread_get(pending_notify_list));
}
}
@@ -790,8 +785,7 @@ static void requeue_cluster_request(void)
struct vdi_op_message *msg;
size_t size;
- list_for_each_entry(req, main_thread_get(pending_notify_list),
- pending_list) {
+ list_for_each_entry(req, main_thread_get(pending_notify_list)) {
/*
* ->notify() was called and succeeded but after that
* this node session-timeouted and sd_notify_handler
@@ -806,15 +800,13 @@ static void requeue_cluster_request(void)
free(msg);
}
- list_for_each_entry(req, main_thread_get(pending_block_list),
- pending_list) {
+ list_for_each_entry(req, main_thread_get(pending_block_list)) {
switch (req->status) {
case REQUEST_INIT:
/* this request has never been executed, re-queue it */
sd_debug("requeue a block request, op: %s",
op_name(req->op));
- list_del(&req->pending_list,
- main_thread_get(pending_block_list));
+ list_del(req, main_thread_get(pending_block_list));
queue_cluster_request(req);
break;
case REQUEST_QUEUED:
@@ -1024,10 +1016,10 @@ int create_cluster(int port, int64_t zone, int nr_vnodes,
sys->cinfo.status = SD_STATUS_WAIT;
main_thread_set(pending_block_list,
- xzalloc(sizeof(struct list_head)));
+ xzalloc(sizeof(struct list_pending_head)));
INIT_LIST_HEAD(main_thread_get(pending_block_list));
main_thread_set(pending_notify_list,
- xzalloc(sizeof(struct list_head)));
+ xzalloc(sizeof(struct list_pending_head)));
INIT_LIST_HEAD(main_thread_get(pending_notify_list));
INIT_LIST_HEAD(&sys->local_req_queue);
diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index 07ce50b..f1b1d6f 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -58,8 +58,10 @@ struct object_cache {
struct hlist_node hash; /* VDI is linked to the global hash lists */
/* For faster object search */
RB_ROOT(rb_lru_root, struct object_cache_entry, node) lru_tree;
- struct list_head lru_head; /* Per VDI LRU list for reclaimer */
- struct list_head dirty_head; /* Dirty objects linked to this list */
+ /* Per VDI LRU list for reclaimer */
+ LIST_HEAD(, struct object_cache_entry, lru_list) lru_head;
+ /* Dirty objects linked to this list */
+ LIST_HEAD(, struct object_cache_entry, dirty_list) dirty_head;
int push_efd; /* Used to synchronize between pusher and push threads */
uatomic_bool in_push; /* Whether if pusher is running */
@@ -250,7 +252,7 @@ static void del_from_dirty_list(struct object_cache_entry *entry)
{
struct object_cache *oc = entry->oc;
- list_del(&entry->dirty_list, &oc->dirty_head);
+ list_del(entry, &oc->dirty_head);
uatomic_dec(&oc->dirty_count);
}
@@ -258,7 +260,7 @@ static void add_to_dirty_list(struct object_cache_entry *entry)
{
struct object_cache *oc = entry->oc;
- list_add_tail(&entry->dirty_list, &oc->dirty_head);
+ list_add_tail(entry, &oc->dirty_head);
/* FIXME read sys->status atomically */
if (uatomic_add_return(&oc->dirty_count, 1) > MAX_DIRTY_OBJECT_COUNT
&& !uatomic_is_true(&oc->in_push)
@@ -272,9 +274,9 @@ free_cache_entry(struct object_cache_entry *entry)
struct object_cache *oc = entry->oc;
rb_erase(entry, &oc->lru_tree);
- list_del(&entry->lru_list, &oc->lru_head);
+ list_del(entry, &oc->lru_head);
oc->total_count--;
- if (list_linked(&entry->dirty_list, &oc->dirty_head))
+ if (list_linked(entry, &oc->dirty_head))
del_from_dirty_list(entry);
sd_destroy_lock(&entry->lock);
free(entry);
@@ -391,7 +393,7 @@ static int read_cache_object(struct object_cache_entry *entry, void *buf,
if (ret == SD_RES_SUCCESS) {
write_lock_cache(oc);
- list_move_tail(&entry->lru_list, &oc->lru_head);
+ list_move_tail(entry, &oc->lru_head);
unlock_cache(oc);
}
return ret;
@@ -417,10 +419,10 @@ static int write_cache_object(struct object_cache_entry *entry, void *buf,
write_lock_cache(oc);
if (writeback) {
entry->bmap |= calc_object_bmap(oid, count, offset);
- if (!list_linked(&entry->dirty_list, &oc->dirty_head))
+ if (!list_linked(entry, &oc->dirty_head))
add_to_dirty_list(entry);
}
- list_move_tail(&entry->lru_list, &oc->lru_head);
+ list_move_tail(entry, &oc->lru_head);
unlock_cache(oc);
unlock_entry(entry);
@@ -517,7 +519,7 @@ static void do_reclaim_object(struct object_cache *oc)
uint32_t cap;
write_lock_cache(oc);
- list_for_each_entry(entry, &oc->lru_head, lru_list) {
+ list_for_each_entry(entry, &oc->lru_head) {
oid = idx_to_oid(oc->vid, entry_idx(entry));
if (entry_in_use(entry)) {
sd_debug("%"PRIx64" is in use, skip...", oid);
@@ -688,7 +690,7 @@ static void add_to_lru_cache(struct object_cache *oc, uint32_t idx, bool create)
if (unlikely(lru_tree_insert(&oc->lru_tree, entry)))
panic("the object already exist");
uatomic_add(&gcache.capacity, CACHE_OBJECT_SIZE);
- list_add_tail(&entry->lru_list, &oc->lru_head);
+ list_add_tail(entry, &oc->lru_head);
oc->total_count++;
if (create) {
/* Cache lock assure it is not raced with pusher */
@@ -910,7 +912,7 @@ static int object_cache_push(struct object_cache *oc)
}
uatomic_set(&oc->push_count, uatomic_read(&oc->dirty_count));
- list_for_each_entry(entry, &oc->dirty_head, dirty_list) {
+ list_for_each_entry(entry, &oc->dirty_head) {
struct push_work *pw;
get_cache_entry(entry);
@@ -959,7 +961,7 @@ void object_cache_delete(uint32_t vid)
sd_unlock(&hashtable_lock[h]);
write_lock_cache(cache);
- list_for_each_entry(entry, &cache->lru_head, lru_list) {
+ list_for_each_entry(entry, &cache->lru_head) {
free_cache_entry(entry);
uatomic_sub(&gcache.capacity, CACHE_OBJECT_SIZE);
}
diff --git a/sheep/ops.c b/sheep/ops.c
index 05ba009..b4fc77d 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -366,7 +366,7 @@ static int local_get_store_list(struct request *req)
struct strbuf buf = STRBUF_INIT;
struct store_driver *driver;
- list_for_each_entry(driver, &store_drivers, list) {
+ list_for_each_entry(driver, &store_drivers) {
strbuf_addf(&buf, "%s ", driver->name);
}
req->rp.data_length = strbuf_copyout(&buf, req->data, req->data_length);
diff --git a/sheep/request.c b/sheep/request.c
index 863b9a5..28781ad 100644
--- a/sheep/request.c
+++ b/sheep/request.c
@@ -15,9 +15,9 @@
static void requeue_request(struct request *req);
-static void del_requeue_request(struct request *req, struct list_head *head)
+static void del_requeue_request(struct request *req, struct list_request_head *head)
{
- list_del(&req->request_list, head);
+ list_del(req, head);
requeue_request(req);
}
@@ -84,7 +84,7 @@ static void io_op_done(struct work *work)
*/
static inline void sleep_on_wait_queue(struct request *req)
{
- list_add_tail(&req->request_list, &sys->req_wait_queue);
+ list_add_tail(req, &sys->req_wait_queue);
}
static void gateway_op_done(struct work *work)
@@ -203,11 +203,12 @@ static bool request_in_recovery(struct request *req)
void wakeup_requests_on_epoch(void)
{
struct request *req;
- LIST_HEAD(pending_list);
+ struct list_request_head pending_list =
+ LIST_HEAD_INITIALIZER(pending_list);
list_splice_init(&sys->req_wait_queue, &pending_list);
- list_for_each_entry(req, &pending_list, request_list) {
+ list_for_each_entry(req, &pending_list) {
switch (req->rp.result) {
case SD_RES_OLD_NODE_VER:
/*
@@ -240,11 +241,12 @@ void wakeup_requests_on_epoch(void)
void wakeup_requests_on_oid(uint64_t oid)
{
struct request *req;
- LIST_HEAD(pending_list);
+ struct list_request_head pending_list =
+ LIST_HEAD_INITIALIZER(pending_list);
list_splice_init(&sys->req_wait_queue, &pending_list);
- list_for_each_entry(req, &pending_list, request_list) {
+ list_for_each_entry(req, &pending_list) {
if (req->local_oid != oid)
continue;
sd_debug("retry %" PRIx64, req->local_oid);
@@ -256,11 +258,12 @@ void wakeup_requests_on_oid(uint64_t oid)
void wakeup_all_requests(void)
{
struct request *req;
- LIST_HEAD(pending_list);
+ struct list_request_head pending_list =
+ LIST_HEAD_INITIALIZER(pending_list);
list_splice_init(&sys->req_wait_queue, &pending_list);
- list_for_each_entry(req, &pending_list, request_list) {
+ list_for_each_entry(req, &pending_list) {
sd_debug("%"PRIx64, req->rq.obj.oid);
del_requeue_request(req, &pending_list);
}
@@ -492,7 +495,7 @@ worker_fn int exec_local_req(struct sd_req *rq, void *data)
}
pthread_mutex_lock(&sys->local_req_lock);
- list_add_tail(&req->request_list, &sys->local_req_queue);
+ list_add_tail(req, &sys->local_req_queue);
pthread_mutex_unlock(&sys->local_req_lock);
eventfd_xwrite(sys->local_req_efd, 1);
@@ -560,7 +563,7 @@ main_fn void put_request(struct request *req)
clear_client_info(ci);
free_request(req);
} else {
- list_add_tail(&req->request_list, &ci->done_reqs);
+ list_add_tail(req, &ci->done_reqs);
if (ci->tx_req == NULL)
/* There is no request being sent. */
@@ -690,8 +693,8 @@ static void clear_client_info(struct client_info *ci)
sd_debug("connection seems to be dead");
- list_for_each_entry(req, &ci->done_reqs, request_list) {
- list_del(&req->request_list, &ci->done_reqs);
+ list_for_each_entry(req, &ci->done_reqs) {
+ list_del(req, &ci->done_reqs);
free_request(req);
}
@@ -769,9 +772,8 @@ static void client_handler(int fd, int events, void *data)
return;
assert(ci->tx_req == NULL);
- ci->tx_req = list_first_entry(&ci->done_reqs, struct request,
- request_list);
- list_del(&ci->tx_req->request_list, &ci->done_reqs);
+ ci->tx_req = list_first_entry(&ci->done_reqs);
+ list_del(ci->tx_req, &ci->done_reqs);
/*
* Increment refcnt so that the client_info isn't freed while
@@ -856,7 +858,8 @@ int init_unix_domain_socket(const char *dir)
static void local_req_handler(int listen_fd, int events, void *data)
{
struct request *req;
- LIST_HEAD(pending_list);
+ struct list_request_head pending_list =
+ LIST_HEAD_INITIALIZER(pending_list);
if (events & EPOLLERR)
sd_err("request handler error");
@@ -867,8 +870,8 @@ static void local_req_handler(int listen_fd, int events, void *data)
list_splice_init(&sys->local_req_queue, &pending_list);
pthread_mutex_unlock(&sys->local_req_lock);
- list_for_each_entry(req, &pending_list, request_list) {
- list_del(&req->request_list, &pending_list);
+ list_for_each_entry(req, &pending_list) {
+ list_del(req, &pending_list);
queue_request(req);
}
}
diff --git a/sheep/sheep.c b/sheep/sheep.c
index 7d4cd85..84d99a8 100644
--- a/sheep/sheep.c
+++ b/sheep/sheep.c
@@ -20,7 +20,7 @@
#define DEFAULT_OBJECT_DIR "/tmp"
#define LOG_FILE_NAME "sheep.log"
-LIST_HEAD(cluster_drivers);
+struct list_cdrv_head cluster_drivers = LIST_HEAD_INITIALIZER(cluster_drivers);
static const char program_name[] = "sheep";
static const char bind_help[] =
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 5a178ce..83415cb 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -62,20 +62,6 @@
#define worker_fn
#endif
-struct client_info {
- struct connection conn;
-
- struct request *rx_req;
- struct work rx_work;
-
- struct request *tx_req;
- struct work tx_work;
-
- struct list_head done_reqs;
-
- refcnt_t refcnt;
-};
-
enum REQUST_STATUS {
REQUEST_INIT,
REQUEST_QUEUED,
@@ -109,6 +95,22 @@ struct request {
bool stat; /* true if this request is during stat */
};
+LIST_HEAD(list_request_head, struct request, request_list);
+
+struct client_info {
+ struct connection conn;
+
+ struct request *rx_req;
+ struct work rx_work;
+
+ struct request *tx_req;
+ struct work tx_work;
+
+ struct list_request_head done_reqs;
+
+ refcnt_t refcnt;
+};
+
struct system_info {
struct cluster_driver *cdrv;
const char *cdrv_option;
@@ -124,8 +126,8 @@ struct system_info {
int local_req_efd;
pthread_mutex_t local_req_lock;
- struct list_head local_req_queue;
- struct list_head req_wait_queue;
+ struct list_request_head local_req_queue;
+ struct list_request_head req_wait_queue;
int nr_outstanding_reqs;
bool gateway_only;
@@ -231,18 +233,19 @@ int for_each_object_in_stale(int (*func)(uint64_t oid, const char *path,
void *arg);
int for_each_obj_path(int (*func)(const char *path));
-extern struct list_head store_drivers;
+LIST_HEAD(list_sdrv_head, struct store_driver, list);
+extern struct list_sdrv_head store_drivers;
#define add_store_driver(driver) \
static void __attribute__((constructor)) add_ ## driver(void) \
{ \
- list_add(&driver.list, &store_drivers); \
+ list_add(&driver, &store_drivers); \
}
static inline struct store_driver *find_store_driver(const char *name)
{
struct store_driver *driver;
- list_for_each_entry(driver, &store_drivers, list) {
+ list_for_each_entry(driver, &store_drivers) {
if (strcmp(driver->name, name) == 0)
return driver;
}
diff --git a/sheep/store.c b/sheep/store.c
index b0af526..d88d2a3 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -15,7 +15,7 @@ char *obj_path;
char *epoch_path;
struct store_driver *sd_store;
-LIST_HEAD(store_drivers);
+struct list_sdrv_head store_drivers = LIST_HEAD_INITIALIZER(store_drivers);
int update_epoch_log(uint32_t epoch, struct sd_node *nodes, size_t nr_nodes)
{
diff --git a/sheep/trace/trace.c b/sheep/trace/trace.c
index 5fdb580..94dacd0 100644
--- a/sheep/trace/trace.c
+++ b/sheep/trace/trace.c
@@ -18,7 +18,8 @@
/* Intel recommended one for 5 bytes nops (nopl 0x0(%rax,%rax,1)) */
static const unsigned char NOP5[INSN_SIZE] = {0x0f, 0x1f, 0x44, 0x00, 0x00};
-static LIST_HEAD(tracers);
+static LIST_HEAD(, struct tracer, list) tracers =
+ LIST_HEAD_INITIALIZER(tracers);
static __thread int ret_stack_index;
static __thread struct {
const struct caller *caller;
@@ -84,7 +85,7 @@ static struct caller *trace_lookup_ip(unsigned long ip)
void regist_tracer(struct tracer *tracer)
{
- list_add_tail(&tracer->list, &tracers);
+ list_add_tail(tracer, &tracers);
}
static void patch_all_sites(unsigned long addr)
@@ -115,7 +116,7 @@ void trace_function_enter(unsigned long ip, unsigned long *ret_addr)
caller = trace_lookup_ip(ip);
- list_for_each_entry(tracer, &tracers, list) {
+ list_for_each_entry(tracer, &tracers) {
if (tracer->enter && uatomic_is_true(&tracer->enabled)) {
tracer->stack_depth++;
tracer->enter(caller, ret_stack_index);
@@ -142,7 +143,7 @@ unsigned long trace_function_exit(void)
ret_stack_index--;
- list_for_each_entry(tracer, &tracers, list) {
+ list_for_each_entry(tracer, &tracers) {
if (tracer->exit && uatomic_is_true(&tracer->enabled)) {
if (tracer->stack_depth == 0)
/*
@@ -166,7 +167,7 @@ static size_t count_enabled_tracers(void)
size_t nr = 0;
struct tracer *t;
- list_for_each_entry(t, &tracers, list) {
+ list_for_each_entry(t, &tracers) {
if (uatomic_is_true(&t->enabled))
nr++;
}
@@ -178,7 +179,7 @@ static struct tracer *find_tracer(const char *name)
{
struct tracer *t;
- list_for_each_entry(t, &tracers, list) {
+ list_for_each_entry(t, &tracers) {
if (strcmp(t->name, name) == 0)
return t;
}
@@ -242,7 +243,7 @@ size_t trace_status(char *buf)
struct tracer *t;
char *p = buf;
- list_for_each_entry(t, &tracers, list) {
+ list_for_each_entry(t, &tracers) {
strcpy(p, t->name);
p += strlen(p);
@@ -450,7 +451,7 @@ void trace_cleanup(void)
{
struct tracer *t;
- list_for_each_entry(t, &tracers, list)
+ list_for_each_entry(t, &tracers)
trace_disable(t->name);
call_on_worker_threads(__trace_cleanup);
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 490f69e..31215c0 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -735,7 +735,8 @@ struct deletion_work {
uint32_t *buf;
};
-static LIST_HEAD(deletion_work_list);
+static LIST_HEAD(, struct deletion_work, list) deletion_work_list =
+ LIST_HEAD_INITIALIZER(deletion_work_list);
static int delete_inode(struct deletion_work *dw)
{
@@ -855,7 +856,7 @@ static void delete_one_done(struct work *work)
return;
}
- list_del(&dw->list, &deletion_work_list);
+ list_del(dw, &deletion_work_list);
put_request(req);
@@ -863,8 +864,7 @@ static void delete_one_done(struct work *work)
free(dw);
if (!list_empty(&deletion_work_list)) {
- dw = list_first_entry(&deletion_work_list,
- struct deletion_work, list);
+ dw = list_first_entry(&deletion_work_list);
queue_work(sys->deletion_wqueue, &dw->work);
}
@@ -1005,10 +1005,10 @@ static int start_deletion(struct request *req, uint32_t vid)
refcount_inc(&req->refcnt);
if (list_empty(&deletion_work_list)) {
- list_add_tail(&dw->list, &deletion_work_list);
+ list_add_tail(dw, &deletion_work_list);
queue_work(sys->deletion_wqueue, &dw->work);
} else
- list_add_tail(&dw->list, &deletion_work_list);
+ list_add_tail(dw, &deletion_work_list);
out:
return SD_RES_SUCCESS;
err:
diff --git a/shepherd/shepherd.c b/shepherd/shepherd.c
index 449da0f..2e26aae 100644
--- a/shepherd/shepherd.c
+++ b/shepherd/shepherd.c
@@ -60,7 +60,8 @@ struct sheep {
struct list_node join_wait_list;
};
-static LIST_HEAD(sheep_list_head);
+static LIST_HEAD(, struct sheep, sheep_list) sheep_list_head =
+ LIST_HEAD_INITIALIZER(sheep_list_head);
static bool running;
static const char *progname;
@@ -77,7 +78,7 @@ static int build_node_array(struct sd_node *nodes)
struct sheep *s;
i = 0;
- list_for_each_entry(s, &sheep_list_head, sheep_list) {
+ list_for_each_entry(s, &sheep_list_head) {
if (s->state != SHEEP_STATE_JOINED)
continue;
@@ -91,7 +92,7 @@ static struct sheep *find_sheep_by_nid(struct node_id *id)
{
struct sheep *s;
- list_for_each_entry(s, &sheep_list_head, sheep_list) {
+ list_for_each_entry(s, &sheep_list_head) {
if (!node_id_cmp(&s->node.nid, id))
return s;
}
@@ -121,7 +122,7 @@ static int notify_remove_sheep(struct sheep *leaving)
snd.type = SPH_SRV_MSG_REMOVE;
snd.body_len = sizeof(struct sd_node);
- list_for_each_entry(s, &sheep_list_head, sheep_list) {
+ list_for_each_entry(s, &sheep_list_head) {
if (s->state != SHEEP_STATE_JOINED)
continue;
@@ -139,7 +140,8 @@ static int notify_remove_sheep(struct sheep *leaving)
return failed;
}
-static LIST_HEAD(join_wait_queue);
+static LIST_HEAD(, struct sheep, join_wait_list) join_wait_queue =
+ LIST_HEAD_INITIALIZER(join_wait_queue);
static void remove_handler(int fd, int events, void *data)
{
@@ -150,7 +152,7 @@ static void remove_handler(int fd, int events, void *data)
sd_debug("removed sheeps");
remove:
- list_for_each_entry(s, &sheep_list_head, sheep_list) {
+ list_for_each_entry(s, &sheep_list_head) {
if (s->state != SHEEP_STATE_LEAVING)
continue;
@@ -181,8 +183,8 @@ del:
unregister_event(s->fd);
close(s->fd);
- list_del(&s->sheep_list, &sheep_list_head);
- list_del(&s->join_wait_list, &join_wait_queue);
+ list_del(s, &sheep_list_head);
+ list_del(s, &join_wait_queue);
free(s);
if (--nr_removed)
@@ -203,9 +205,8 @@ retry:
if (list_empty(&join_wait_queue))
return nr_failed;
- waiting = list_first_entry(&join_wait_queue,
- struct sheep, join_wait_list);
- list_del(&waiting->join_wait_list, &join_wait_queue);
+ waiting = list_first_entry(&join_wait_queue);
+ list_del(waiting, &join_wait_queue);
memset(&snd, 0, sizeof(snd));
snd.type = SPH_SRV_MSG_JOIN_RETRY;
@@ -244,7 +245,7 @@ static void sph_handle_join(struct sph_msg *msg, struct sheep *sheep)
}
free(buf);
- list_add(&sheep->join_wait_list, &join_wait_queue);
+ list_add(sheep, &join_wait_queue);
sd_debug("there is already a joining sheep");
return;
@@ -357,7 +358,7 @@ static void sph_handle_accept(struct sph_msg *msg, struct sheep *sheep)
join_node_finish->nodes[join_node_finish->nr_nodes++] =
joining_sheep->node;
- list_for_each_entry(s, &sheep_list_head, sheep_list) {
+ list_for_each_entry(s, &sheep_list_head) {
if (s->state != SHEEP_STATE_JOINED)
continue;
@@ -420,7 +421,7 @@ static void sph_handle_notify(struct sph_msg *msg, struct sheep *sheep)
notify_forward->from_node = sheep->node;
- list_for_each_entry(s, &sheep_list_head, sheep_list) {
+ list_for_each_entry(s, &sheep_list_head) {
if (s->state != SHEEP_STATE_JOINED)
continue;
@@ -454,7 +455,7 @@ static void sph_handle_block(struct sph_msg *msg, struct sheep *sheep)
snd.type = SPH_SRV_MSG_BLOCK_FORWARD;
snd.body_len = sizeof(struct sd_node);
- list_for_each_entry(s, &sheep_list_head, sheep_list) {
+ list_for_each_entry(s, &sheep_list_head) {
ssize_t wbytes;
if (s->state != SHEEP_STATE_JOINED)
@@ -488,7 +489,7 @@ static void sph_handle_leave(struct sph_msg *msg, struct sheep *sheep)
snd.type = SPH_SRV_MSG_LEAVE_FORWARD;
snd.body_len = sizeof(struct sd_node);
- list_for_each_entry(s, &sheep_list_head, sheep_list) {
+ list_for_each_entry(s, &sheep_list_head) {
ssize_t wbytes;
if (s->state != SHEEP_STATE_JOINED)
@@ -584,7 +585,7 @@ static void sheep_accept_handler(int fd, int events, void *data)
goto clean;
}
- list_add_tail(&new_sheep->sheep_list, &sheep_list_head);
+ list_add_tail(new_sheep, &sheep_list_head);
new_sheep->state = SHEEP_STATE_CONNECTED;
sd_info("accepted new sheep connection");
diff --git a/tests/unit/sheep/mock_sheep.c b/tests/unit/sheep/mock_sheep.c
index 5454735..6f2eda3 100644
--- a/tests/unit/sheep/mock_sheep.c
+++ b/tests/unit/sheep/mock_sheep.c
@@ -14,4 +14,4 @@
#include "sheep_priv.h"
struct system_info *sys;
-LIST_HEAD(cluster_drivers);
+struct list_cdrv_head cluster_drivers = LIST_HEAD_INITIALIZER(cluster_drivers);
--
1.8.1.2
More information about the sheepdog
mailing list