]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/fib_hash.c
[IPV4] FIB_HASH : Avoid unecessary loop in fn_hash_dump_zone()
[linux-2.6-omap-h63xx.git] / net / ipv4 / fib_hash.c
index 527a6e0af5b60eb48b9e15459e8877db10c29db8..0dfee27cfbcd8c80364ddf2bace37e955b8b55d8 100644 (file)
@@ -444,6 +444,9 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
                        struct fib_info *fi_drop;
                        u8 state;
 
+                       if (fi->fib_treeref > 1)
+                               goto out;
+
                        write_lock_bh(&fib_hash_lock);
                        fi_drop = fa->fa_info;
                        fa->fa_info = fi;
@@ -718,19 +721,18 @@ fn_hash_dump_zone(struct sk_buff *skb, struct netlink_callback *cb,
 {
        int h, s_h;
 
+       if (fz->fz_hash == NULL)
+               return skb->len;
        s_h = cb->args[3];
-       for (h=0; h < fz->fz_divisor; h++) {
-               if (h < s_h) continue;
-               if (h > s_h)
-                       memset(&cb->args[4], 0,
-                              sizeof(cb->args) - 4*sizeof(cb->args[0]));
-               if (fz->fz_hash == NULL ||
-                   hlist_empty(&fz->fz_hash[h]))
+       for (h = s_h; h < fz->fz_divisor; h++) {
+               if (hlist_empty(&fz->fz_hash[h]))
                        continue;
-               if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h])<0) {
+               if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h]) < 0) {
                        cb->args[3] = h;
                        return -1;
                }
+               memset(&cb->args[4], 0,
+                      sizeof(cb->args) - 4*sizeof(cb->args[0]));
        }
        cb->args[3] = h;
        return skb->len;
@@ -746,14 +748,13 @@ static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, struct netlin
        read_lock(&fib_hash_lock);
        for (fz = table->fn_zone_list, m=0; fz; fz = fz->fz_next, m++) {
                if (m < s_m) continue;
-               if (m > s_m)
-                       memset(&cb->args[3], 0,
-                              sizeof(cb->args) - 3*sizeof(cb->args[0]));
                if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) {
                        cb->args[2] = m;
                        read_unlock(&fib_hash_lock);
                        return -1;
                }
+               memset(&cb->args[3], 0,
+                      sizeof(cb->args) - 3*sizeof(cb->args[0]));
        }
        read_unlock(&fib_hash_lock);
        cb->args[2] = m;