netfilter: ipset: Prepare the ipset core to use RCU at set level
[cascardo/linux.git] / net / netfilter / ipset / ip_set_core.c
index 87b4182..2b21a19 100644 (file)
@@ -209,15 +209,15 @@ ip_set_type_register(struct ip_set_type *type)
                pr_warn("ip_set type %s, family %s with revision min %u already registered!\n",
                        type->name, family_name(type->family),
                        type->revision_min);
-               ret = -EINVAL;
-               goto unlock;
+               ip_set_type_unlock();
+               return -EINVAL;
        }
        list_add_rcu(&type->list, &ip_set_type_list);
        pr_debug("type %s, family %s, revision %u:%u registered.\n",
                 type->name, family_name(type->family),
                 type->revision_min, type->revision_max);
-unlock:
        ip_set_type_unlock();
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(ip_set_type_register);
@@ -231,12 +231,12 @@ ip_set_type_unregister(struct ip_set_type *type)
                pr_warn("ip_set type %s, family %s with revision min %u not registered\n",
                        type->name, family_name(type->family),
                        type->revision_min);
-               goto unlock;
+               ip_set_type_unlock();
+               return;
        }
        list_del_rcu(&type->list);
        pr_debug("type %s, family %s with revision min %u unregistered.\n",
                 type->name, family_name(type->family), type->revision_min);
-unlock:
        ip_set_type_unlock();
 
        synchronize_rcu();
@@ -531,16 +531,16 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
            !(opt->family == set->family || set->family == NFPROTO_UNSPEC))
                return 0;
 
-       read_lock_bh(&set->lock);
+       rcu_read_lock_bh();
        ret = set->variant->kadt(set, skb, par, IPSET_TEST, opt);
-       read_unlock_bh(&set->lock);
+       rcu_read_unlock_bh();
 
        if (ret == -EAGAIN) {
                /* Type requests element to be completed */
                pr_debug("element must be completed, ADD is triggered\n");
-               write_lock_bh(&set->lock);
+               spin_lock_bh(&set->lock);
                set->variant->kadt(set, skb, par, IPSET_ADD, opt);
-               write_unlock_bh(&set->lock);
+               spin_unlock_bh(&set->lock);
                ret = 1;
        } else {
                /* --return-nomatch: invert matched element */
@@ -570,9 +570,9 @@ ip_set_add(ip_set_id_t index, const struct sk_buff *skb,
            !(opt->family == set->family || set->family == NFPROTO_UNSPEC))
                return -IPSET_ERR_TYPE_MISMATCH;
 
-       write_lock_bh(&set->lock);
+       spin_lock_bh(&set->lock);
        ret = set->variant->kadt(set, skb, par, IPSET_ADD, opt);
-       write_unlock_bh(&set->lock);
+       spin_unlock_bh(&set->lock);
 
        return ret;
 }
@@ -593,9 +593,9 @@ ip_set_del(ip_set_id_t index, const struct sk_buff *skb,
            !(opt->family == set->family || set->family == NFPROTO_UNSPEC))
                return -IPSET_ERR_TYPE_MISMATCH;
 
-       write_lock_bh(&set->lock);
+       spin_lock_bh(&set->lock);
        ret = set->variant->kadt(set, skb, par, IPSET_DEL, opt);
-       write_unlock_bh(&set->lock);
+       spin_unlock_bh(&set->lock);
 
        return ret;
 }
@@ -880,7 +880,7 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb,
        set = kzalloc(sizeof(struct ip_set), GFP_KERNEL);
        if (!set)
                return -ENOMEM;
-       rwlock_init(&set->lock);
+       spin_lock_init(&set->lock);
        strlcpy(set->name, name, IPSET_MAXNAMELEN);
        set->family = family;
        set->revision = revision;
@@ -1062,9 +1062,9 @@ ip_set_flush_set(struct ip_set *set)
 {
        pr_debug("set: %s\n",  set->name);
 
-       write_lock_bh(&set->lock);
+       spin_lock_bh(&set->lock);
        set->variant->flush(set);
-       write_unlock_bh(&set->lock);
+       spin_unlock_bh(&set->lock);
 }
 
 static int
@@ -1377,9 +1377,9 @@ dump_last:
                                set->variant->uref(set, cb, true);
                        /* Fall through and add elements */
                default:
-                       read_lock_bh(&set->lock);
+                       rcu_read_lock_bh();
                        ret = set->variant->list(set, skb, cb);
-                       read_unlock_bh(&set->lock);
+                       rcu_read_unlock_bh();
                        if (!cb->args[IPSET_CB_ARG0])
                                /* Set is done, proceed with next one */
                                goto next_set;
@@ -1462,9 +1462,9 @@ call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set,
        bool eexist = flags & IPSET_FLAG_EXIST, retried = false;
 
        do {
-               write_lock_bh(&set->lock);
+               spin_lock_bh(&set->lock);
                ret = set->variant->uadt(set, tb, adt, &lineno, flags, retried);
-               write_unlock_bh(&set->lock);
+               spin_unlock_bh(&set->lock);
                retried = true;
        } while (ret == -EAGAIN &&
                 set->variant->resize &&
@@ -1644,9 +1644,9 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb,
                             set->type->adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
-       read_lock_bh(&set->lock);
+       rcu_read_lock_bh();
        ret = set->variant->uadt(set, tb, IPSET_TEST, NULL, 0, 0);
-       read_unlock_bh(&set->lock);
+       rcu_read_unlock_bh();
        /* Userspace can't trigger element to be re-added */
        if (ret == -EAGAIN)
                ret = 1;