Currently we return EINVAL for "instance exists", "allocation failed" and
"module unloaded below us", which is completely inapproriate.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
instance_create(u_int16_t group_num, int pid)
{
struct nfulnl_instance *inst;
instance_create(u_int16_t group_num, int pid)
{
struct nfulnl_instance *inst;
write_lock_bh(&instances_lock);
if (__instance_lookup(group_num)) {
write_lock_bh(&instances_lock);
if (__instance_lookup(group_num)) {
goto out_unlock;
}
inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
goto out_unlock;
}
inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
+ if (!inst) {
+ err = -ENOMEM;
if (!try_module_get(THIS_MODULE)) {
kfree(inst);
if (!try_module_get(THIS_MODULE)) {
kfree(inst);
out_unlock:
write_unlock_bh(&instances_lock);
out_unlock:
write_unlock_bh(&instances_lock);
}
static void __nfulnl_flush(struct nfulnl_instance *inst);
}
static void __nfulnl_flush(struct nfulnl_instance *inst);
inst = instance_create(group_num,
NETLINK_CB(skb).pid);
inst = instance_create(group_num,
NETLINK_CB(skb).pid);
- if (!inst) {
- ret = -EINVAL;
+ if (IS_ERR(inst)) {
+ ret = PTR_ERR(inst);
static struct nfqnl_instance *
instance_create(u_int16_t queue_num, int pid)
{
static struct nfqnl_instance *
instance_create(u_int16_t queue_num, int pid)
{
- struct nfqnl_instance *inst = NULL;
+ struct nfqnl_instance *inst;
spin_lock(&instances_lock);
spin_lock(&instances_lock);
- if (instance_lookup(queue_num))
+ if (instance_lookup(queue_num)) {
+ err = -EEXIST;
inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
+ if (!inst) {
+ err = -ENOMEM;
inst->queue_num = queue_num;
inst->peer_pid = pid;
inst->queue_num = queue_num;
inst->peer_pid = pid;
INIT_LIST_HEAD(&inst->queue_list);
INIT_RCU_HEAD(&inst->rcu);
INIT_LIST_HEAD(&inst->queue_list);
INIT_RCU_HEAD(&inst->rcu);
- if (!try_module_get(THIS_MODULE))
+ if (!try_module_get(THIS_MODULE)) {
+ err = -EAGAIN;
h = instance_hashfn(queue_num);
hlist_add_head_rcu(&inst->hlist, &instance_table[h]);
h = instance_hashfn(queue_num);
hlist_add_head_rcu(&inst->hlist, &instance_table[h]);
kfree(inst);
out_unlock:
spin_unlock(&instances_lock);
kfree(inst);
out_unlock:
spin_unlock(&instances_lock);
}
static void nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn,
}
static void nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn,
goto err_out_unlock;
}
queue = instance_create(queue_num, NETLINK_CB(skb).pid);
goto err_out_unlock;
}
queue = instance_create(queue_num, NETLINK_CB(skb).pid);
- if (!queue) {
- ret = -EINVAL;
+ if (IS_ERR(queue)) {
+ ret = PTR_ERR(queue);
goto err_out_unlock;
}
break;
goto err_out_unlock;
}
break;