rcuja: fix duplicate node/key support
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sun, 26 Aug 2012 00:57:43 +0000 (20:57 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 14 May 2013 14:22:23 +0000 (16:22 +0200)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
rcuja/rcuja.c

index bb0393c0fc9c703a9e97ca9aeb1cfb7eeeab65de..0fca3db8441b33eb7b4bc92124a58cad320fa9c1 100644 (file)
@@ -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)
This page took 0.026072 seconds and 4 git commands to generate.