]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/llc/llc_sap.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
[mv-sheeva.git] / net / llc / llc_sap.c
index 94cb706f6cc4db1debb87edbb6cfa50fec7a1c7e..ad6e6e1cf22fce1eefa43d1726537d3b5bf644dc 100644 (file)
@@ -321,10 +321,12 @@ static struct sock *llc_lookup_dgram(struct llc_sap *sap,
 {
        struct sock *rc;
        struct hlist_nulls_node *node;
+       int slot = llc_sk_laddr_hashfn(sap, laddr);
+       struct hlist_nulls_head *laddr_hb = &sap->sk_laddr_hash[slot];
 
        rcu_read_lock_bh();
 again:
-       sk_nulls_for_each_rcu(rc, node, &sap->sk_list) {
+       sk_nulls_for_each_rcu(rc, node, laddr_hb) {
                if (llc_dgram_match(sap, laddr, rc)) {
                        /* Extra checks required by SLAB_DESTROY_BY_RCU */
                        if (unlikely(!atomic_inc_not_zero(&rc->sk_refcnt)))
@@ -338,6 +340,13 @@ again:
                }
        }
        rc = NULL;
+       /*
+        * if the nulls value we got at the end of this lookup is
+        * not the expected one, we must restart lookup.
+        * We probably met an item that was moved to another chain.
+        */
+       if (unlikely(get_nulls_value(node) != slot))
+               goto again;
 found:
        rcu_read_unlock_bh();
        return rc;