[sheepdog] [RFC PATCH 2/3] add strict check in list_del and list_linked
MORITA Kazutaka
morita.kazutaka at gmail.com
Wed Sep 25 20:12:10 CEST 2013
From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
This adds a list_head argument to list_del() and list_linked() to
ensure that the specified list_node is linked to the head.
This prepares for the next patch.
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
dog/treeview.c | 2 +-
include/list.h | 34 +++++++++++++++++++++++++++-------
include/util.h | 1 -
lib/logger.c | 1 +
lib/util.c | 1 +
lib/work.c | 4 ++--
sheep/cluster/corosync.c | 19 +++++++++++++------
sheep/cluster/shepherd.c | 5 ++++-
sheep/cluster/zookeeper.c | 4 ++--
sheep/group.c | 15 ++++++++++-----
sheep/object_cache.c | 8 ++++----
sheep/request.c | 18 +++++++++---------
sheep/vdi.c | 2 +-
shepherd/shepherd.c | 10 +++++-----
14 files changed, 80 insertions(+), 44 deletions(-)
diff --git a/dog/treeview.c b/dog/treeview.c
index c5bad44..c407f2d 100644
--- a/dog/treeview.c
+++ b/dog/treeview.c
@@ -13,7 +13,7 @@
#include <string.h>
#include <stdint.h>
-#include "util.h"
+#include "list.h"
#include "treeview.h"
#ifndef MAX_DEPTH
diff --git a/include/list.h b/include/list.h
index c1bd583..03250ae 100644
--- a/include/list.h
+++ b/include/list.h
@@ -5,7 +5,7 @@
#include <stdbool.h>
-#include "compiler.h"
+#include "util.h"
struct list_node {
struct list_node *next;
@@ -44,11 +44,6 @@ static inline bool list_empty(const struct list_head *head)
return head->n.next == &head->n;
}
-static inline bool list_linked(const struct list_node *node)
-{
- return node->next != NULL;
-}
-
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
@@ -69,6 +64,29 @@ static inline bool list_linked(const struct list_node *node)
typeof(*LOCAL(n)), \
member))
+static inline bool __list_linked(const struct list_node *node,
+ const struct list_head *head)
+{
+ struct list_node *pos;
+
+ list_for_each(pos, head) {
+ if (pos == node)
+ return true;
+ }
+
+ return false;
+}
+
+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));
+
+ return ret;
+}
+
static inline void __list_add(struct list_node *new,
struct list_node *prev,
struct list_node *next)
@@ -100,8 +118,10 @@ static inline void __list_del_entry(struct list_node *entry)
__list_del(entry->prev, entry->next);
}
-static inline void list_del(struct list_node *entry)
+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);
entry->next = entry->prev = NULL;
}
diff --git a/include/util.h b/include/util.h
index fb59192..05fd8dc 100644
--- a/include/util.h
+++ b/include/util.h
@@ -14,7 +14,6 @@
#include <errno.h>
#include "logger.h"
-#include "list.h"
#include "compiler.h"
#define SECTOR_SIZE (1U << 9)
diff --git a/lib/logger.c b/lib/logger.c
index 6c6a315..5a75498 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -36,6 +36,7 @@
#include <linux/limits.h>
#include "util.h"
+#include "list.h"
static bool colorize;
static const char * const log_color[] = {
diff --git a/lib/util.c b/lib/util.c
index 7c7785d..bde6833 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -21,6 +21,7 @@
#include <fcntl.h>
#include "util.h"
+#include "list.h"
mode_t sd_def_dmode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
mode_t sd_def_fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
diff --git a/lib/work.c b/lib/work.c
index ec626e8..f88056e 100644
--- a/lib/work.c
+++ b/lib/work.c
@@ -249,7 +249,7 @@ static void worker_thread_request_done(int fd, int events, void *data)
while (!list_empty(&list)) {
work = list_first_entry(&list, struct work, w_list);
- list_del(&work->w_list);
+ list_del(&work->w_list, &list);
work->done(work);
uatomic_dec(&wi->nr_workers);
@@ -303,7 +303,7 @@ retest:
work = list_first_entry(&wi->q.pending_list,
struct work, w_list);
- list_del(&work->w_list);
+ list_del(&work->w_list, &wi->q.pending_list);
pthread_mutex_unlock(&wi->pending_lock);
if (work->fn)
diff --git a/sheep/cluster/corosync.c b/sheep/cluster/corosync.c
index acc9e1c..7898c73 100644
--- a/sheep/cluster/corosync.c
+++ b/sheep/cluster/corosync.c
@@ -376,12 +376,16 @@ static void __corosync_dispatch(void)
while (!list_empty(&corosync_block_event_list) ||
!list_empty(&corosync_nonblock_event_list)) {
- if (!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);
- else
+ block = false;
+ } else {
cevent = list_first_entry(&corosync_block_event_list,
typeof(*cevent), list);
+ block = true;
+ }
join_finished = update_join_status(cevent);
@@ -398,7 +402,10 @@ static void __corosync_dispatch(void)
}
}
- list_del(&cevent->list);
+ if (block)
+ list_del(&cevent->list, &corosync_block_event_list);
+ else
+ list_del(&cevent->list, &corosync_nonblock_event_list);
free(cevent->msg);
free(cevent);
}
@@ -461,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);
+ list_del(&cevent->list, &corosync_block_event_list);
free(cevent->msg);
free(cevent);
}
@@ -581,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);
+ list_del(&cevent->list, &corosync_nonblock_event_list);
free(cevent->msg);
free(cevent);
continue;
@@ -590,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);
+ list_del(&cevent->list, &corosync_block_event_list);
free(cevent->msg);
free(cevent);
}
diff --git a/sheep/cluster/shepherd.c b/sheep/cluster/shepherd.c
index 9453ff8..494af01 100644
--- a/sheep/cluster/shepherd.c
+++ b/sheep/cluster/shepherd.c
@@ -213,7 +213,10 @@ static bool sph_process_event(void)
}
remove:
- list_del(&ev->event_list);
+ if (nonblock)
+ list_del(&ev->event_list, &nonblocked_event_list);
+ else
+ list_del(&ev->event_list, &blocked_event_list);
free(ev->msg);
free(ev);
diff --git a/sheep/cluster/zookeeper.c b/sheep/cluster/zookeeper.c
index b3966bc..18c7ef4 100644
--- a/sheep/cluster/zookeeper.c
+++ b/sheep/cluster/zookeeper.c
@@ -902,7 +902,7 @@ static void block_event_list_del(struct zk_node *n)
list_for_each_entry(ev, &zk_block_list, list) {
if (node_eq(&ev->node, &n->node)) {
- list_del(&ev->list);
+ list_del(&ev->list, &zk_block_list);
free(ev);
}
}
@@ -945,7 +945,7 @@ static void zk_handle_unblock(struct zk_event *ev)
block = list_first_entry(&zk_block_list, typeof(*block), list);
sd_notify_handler(&ev->sender.node, ev->buf, ev->buf_len);
- list_del(&block->list);
+ list_del(&block->list, &zk_block_list);
free(block);
}
diff --git a/sheep/group.c b/sheep/group.c
index 718258f..88afc45 100644
--- a/sheep/group.c
+++ b/sheep/group.c
@@ -248,7 +248,7 @@ static void cluster_op_done(struct work *work)
req->status = REQUEST_DONE;
return;
drop:
- list_del(&req->pending_list);
+ list_del(&req->pending_list, main_thread_get(pending_block_list));
req->rp.result = SD_RES_CLUSTER_ERROR;
put_request(req);
cluster_op_running = false;
@@ -699,15 +699,19 @@ main_fn void sd_notify_handler(const struct sd_node *sender, void *data,
node_to_str(sender));
if (node_is_local(sender)) {
- if (has_process_work(op))
+ if (has_process_work(op)) {
req = list_first_entry(
main_thread_get(pending_block_list),
struct request, pending_list);
- else
+ list_del(&req->pending_list,
+ 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);
+ list_del(&req->pending_list,
+ main_thread_get(pending_notify_list));
+ }
}
if (ret == SD_RES_SUCCESS && has_process_main(op))
@@ -809,7 +813,8 @@ static void requeue_cluster_request(void)
/* 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);
+ list_del(&req->pending_list,
+ main_thread_get(pending_block_list));
queue_cluster_request(req);
break;
case REQUEST_QUEUED:
diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index 4b554cf..07ce50b 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -250,7 +250,7 @@ static void del_from_dirty_list(struct object_cache_entry *entry)
{
struct object_cache *oc = entry->oc;
- list_del(&entry->dirty_list);
+ list_del(&entry->dirty_list, &oc->dirty_head);
uatomic_dec(&oc->dirty_count);
}
@@ -272,9 +272,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);
+ list_del(&entry->lru_list, &oc->lru_head);
oc->total_count--;
- if (list_linked(&entry->dirty_list))
+ if (list_linked(&entry->dirty_list, &oc->dirty_head))
del_from_dirty_list(entry);
sd_destroy_lock(&entry->lock);
free(entry);
@@ -417,7 +417,7 @@ 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))
+ if (!list_linked(&entry->dirty_list, &oc->dirty_head))
add_to_dirty_list(entry);
}
list_move_tail(&entry->lru_list, &oc->lru_head);
diff --git a/sheep/request.c b/sheep/request.c
index 5113fca..863b9a5 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)
+static void del_requeue_request(struct request *req, struct list_head *head)
{
- list_del(&req->request_list);
+ list_del(&req->request_list, head);
requeue_request(req);
}
@@ -217,7 +217,7 @@ void wakeup_requests_on_epoch(void)
assert(is_gateway_op(req->op));
sd_debug("gateway %"PRIx64, req->rq.obj.oid);
req->rq.epoch = sys->cinfo.epoch;
- del_requeue_request(req);
+ del_requeue_request(req, &pending_list);
break;
case SD_RES_NEW_NODE_VER:
/*
@@ -226,7 +226,7 @@ void wakeup_requests_on_epoch(void)
*/
assert(!is_gateway_op(req->op));
sd_debug("peer %"PRIx64, req->rq.obj.oid);
- del_requeue_request(req);
+ del_requeue_request(req, &pending_list);
break;
default:
break;
@@ -248,7 +248,7 @@ void wakeup_requests_on_oid(uint64_t oid)
if (req->local_oid != oid)
continue;
sd_debug("retry %" PRIx64, req->local_oid);
- del_requeue_request(req);
+ del_requeue_request(req, &pending_list);
}
list_splice_init(&pending_list, &sys->req_wait_queue);
}
@@ -262,7 +262,7 @@ void wakeup_all_requests(void)
list_for_each_entry(req, &pending_list, request_list) {
sd_debug("%"PRIx64, req->rq.obj.oid);
- del_requeue_request(req);
+ del_requeue_request(req, &pending_list);
}
}
@@ -691,7 +691,7 @@ 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);
+ list_del(&req->request_list, &ci->done_reqs);
free_request(req);
}
@@ -771,7 +771,7 @@ static void client_handler(int fd, int events, void *data)
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);
+ list_del(&ci->tx_req->request_list, &ci->done_reqs);
/*
* Increment refcnt so that the client_info isn't freed while
@@ -868,7 +868,7 @@ static void local_req_handler(int listen_fd, int events, void *data)
pthread_mutex_unlock(&sys->local_req_lock);
list_for_each_entry(req, &pending_list, request_list) {
- list_del(&req->request_list);
+ list_del(&req->request_list, &pending_list);
queue_request(req);
}
}
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 64f4f9c..490f69e 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -855,7 +855,7 @@ static void delete_one_done(struct work *work)
return;
}
- list_del(&dw->list);
+ list_del(&dw->list, &deletion_work_list);
put_request(req);
diff --git a/shepherd/shepherd.c b/shepherd/shepherd.c
index fd59229..449da0f 100644
--- a/shepherd/shepherd.c
+++ b/shepherd/shepherd.c
@@ -139,6 +139,8 @@ static int notify_remove_sheep(struct sheep *leaving)
return failed;
}
+static LIST_HEAD(join_wait_queue);
+
static void remove_handler(int fd, int events, void *data)
{
struct sheep *s;
@@ -179,8 +181,8 @@ del:
unregister_event(s->fd);
close(s->fd);
- list_del(&s->sheep_list);
- list_del(&s->join_wait_list);
+ list_del(&s->sheep_list, &sheep_list_head);
+ list_del(&s->join_wait_list, &join_wait_queue);
free(s);
if (--nr_removed)
@@ -190,8 +192,6 @@ end:
sd_debug("nodes which failed during remove_handler(): %d", failed);
}
-static LIST_HEAD(join_wait_queue);
-
static int release_joining_sheep(void)
{
ssize_t wbytes;
@@ -205,7 +205,7 @@ retry:
waiting = list_first_entry(&join_wait_queue,
struct sheep, join_wait_list);
- list_del(&waiting->join_wait_list);
+ list_del(&waiting->join_wait_list, &join_wait_queue);
memset(&snd, 0, sizeof(snd));
snd.type = SPH_SRV_MSG_JOIN_RETRY;
--
1.8.1.2
More information about the sheepdog
mailing list