On Sun, Oct 30, 2011 at 09:55:59AM +0100, Antonio Quartulli wrote:
[...]
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, node, head,
hash_entry) {
if (orig_node->dht_hash > ip_key)
tmp_max = USHRT_MAX -
orig_node->dht_hash + ip_key;
else
tmp_max = ip_key - orig_node->dht_hash;
/* this is closest! */
if (tmp_max <= max)
continue;
/* this has already been selected */
if (tmp_max > last_max)
continue;
if (!atomic_inc_not_zero(&orig_node->refcount))
continue;
/* In case of hash collision we can select two
* nodes with the same hash, but we have ensure
* they are different */
if (tmp_max == last_max) {
for (j = 0; j < select; j++)
if (res[j].orig_node ==
orig_node)
break;
if (j < select)
continue;
}
if (!atomic_inc_not_zero(&orig_node->refcount))
continue;
Why do you increase the refcount two times? If it is really required, please add a comment.
max = tmp_max;
if (max_orig_node)
orig_node_free_ref(max_orig_node);
max_orig_node = orig_node;
}
rcu_read_unlock();
}
last_max = max;
if (max_orig_node) {
res[select].type = DHT_CANDIDATE_ORIG;
res[select].orig_node = max_orig_node;
bat_dbg(DBG_ARP, bat_priv, "DHT_SEL_CAND %d: %pM %u\n",
select, max_orig_node->orig, max);
}
if (res[select].type == DHT_CANDIDATE_ME) {
chosen_me = true;
bat_dbg(DBG_ARP, bat_priv, "DHT_SEL_CAND %d: ME %u\n",
select, bat_priv->dht_hash);
}
max_orig_node = NULL;
- }
- return res;
+}
+/*
- Sends the skb payload passed as argument to the candidates selected for
- 'ip'. The skb is copied by means of pskb_copy() and is sent as unicast packet
- to each of the selected candidate. */
+static bool dht_send_data(struct bat_priv *bat_priv, struct sk_buff *skb,
uint32_t ip)
+{
- int i;
- bool ret = false;
- struct neigh_node *neigh_node = NULL;
- struct sk_buff *tmp_skb;
- struct dht_candidate *cand = dht_select_candidates(bat_priv, ip);
- if (!cand)
goto out;
- bat_dbg(DBG_ARP, bat_priv, "DHT_SEND for %pI4\n", &ip);
- for (i = 0; i < DHT_CANDIDATES_NUM; i++) {
if (cand[i].type == DHT_CANDIDATE_ME ||
cand[i].type == DHT_CANDIDATE_NULL) {
continue;
}
no braces are required here.
neigh_node = orig_node_get_router(cand[i].orig_node);
if (!neigh_node)
goto free_orig;
tmp_skb = pskb_copy(skb, GFP_ATOMIC);
tmp_skb = prepare_unicast_packet(tmp_skb, cand[i].orig_node);
if (tmp_skb)
send_skb_packet(tmp_skb, neigh_node->if_incoming,
neigh_node->addr);
/* set ret to true only if we send at least one request */
ret = true;
neigh_node_free_ref(neigh_node);
+free_orig:
orig_node_free_ref(cand[i].orig_node);
- }
+out:
- kfree(cand);
- return ret;
+}