From f2758d14429e06d652479ad3c58d59ca8038da22 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sat, 25 Aug 2012 20:57:43 -0400 Subject: [PATCH] rcuja: fix duplicate node/key support Signed-off-by: Mathieu Desnoyers --- rcuja/rcuja.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/rcuja/rcuja.c b/rcuja/rcuja.c index bb0393c..0fca3db 100644 --- a/rcuja/rcuja.c +++ b/rcuja/rcuja.c @@ -1279,19 +1279,25 @@ end: static int ja_unchain_node(struct cds_ja *ja, struct cds_ja_inode_flag *parent_node_flag, + struct cds_hlist_head *head, struct cds_ja_node *node) { struct cds_ja_shadow_node *shadow_node; - int ret = 0; + struct cds_hlist_node *hlist_node; + int ret = 0, count = 0; shadow_node = rcuja_shadow_lookup_lock(ja->ht, parent_node_flag); if (!shadow_node) return -EAGAIN; /* * Retry if another thread removed all but one of duplicates - * since check. + * since check (that was performed without lock). */ - if (shadow_node->nr_child == 1) { + cds_hlist_for_each_rcu(hlist_node, head, list) { + count++; + } + + if (count == 1) { ret = -EAGAIN; goto end; } @@ -1394,7 +1400,8 @@ retry: ret = ja_detach_node(ja, snapshot, snapshot_ptr, snapshot_n, nr_snapshot, key, node); } else { - ret = ja_unchain_node(ja, node_flag, entry); + ret = ja_unchain_node(ja, snapshot[nr_snapshot - 1], + &hlist_head, match); } } if (ret == -EAGAIN) -- 2.34.1