]> granicus.if.org Git - ipset/commitdiff
Fix hash type expire: release empty hash bucket block
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Wed, 4 Nov 2015 08:48:39 +0000 (09:48 +0100)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Sat, 7 Nov 2015 10:02:43 +0000 (11:02 +0100)
When all entries are expired/all slots are empty, release the bucket.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
kernel/net/netfilter/ipset/ip_set_hash_gen.h

index d774059a60c6ffe698b16dfd5aa6ebb9ec7ddcea..6989fcba9204667b171b08ea09b628112b5b5b09 100644 (file)
@@ -465,7 +465,7 @@ static void
 mtype_expire(struct ip_set *set, struct htype *h)
 {
        struct htable *t;
-       struct hbucket *n;
+       struct hbucket *n, *tmp;
        struct mtype_elem *data;
        u32 i, j, d;
        size_t dsize = set->dsize;
@@ -500,9 +500,15 @@ mtype_expire(struct ip_set *set, struct htype *h)
                        d++;
                }
                if (d >= AHASH_INIT_SIZE) {
-                       struct hbucket *tmp = kzalloc(sizeof(*tmp) +
-                                       (n->size - AHASH_INIT_SIZE) * dsize,
-                                       GFP_ATOMIC);
+                       if (d >= n->size) {
+                               set->ext_size -= ext_size(n->size, dsize);
+                               rcu_assign_pointer(hbucket(t, i), NULL);
+                               kfree_rcu(n, rcu);
+                               continue;
+                       }
+                       tmp = kzalloc(sizeof(*tmp) +
+                                     (n->size - AHASH_INIT_SIZE) * dsize,
+                                     GFP_ATOMIC);
                        if (!tmp)
                                /* Still try to delete expired elements */
                                continue;