Set file->private_data inside ppp_create_interface() to avoid the need for returning the new ppp structure to the caller. Also, make the unit parameter read/write so that caller can still retrieve the PPP unit number assigned to the interface. Avoiding setting ->private_data in the caller will allow for pushing ppp_mutex down when handling the PPPIOCNEWUNIT ioctl (as locking ppp_mutex is required before setting ->private_data). Signed-off-by: Guillaume Nault <g.nault@xxxxxxxxxxxx> --- drivers/net/ppp/ppp_generic.c | 47 +++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index f572b31..ec83b83 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -269,8 +269,7 @@ static void ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound); static void ppp_ccp_closed(struct ppp *ppp); static struct compressor *find_compressor(int type); static void ppp_get_stats(struct ppp *ppp, struct ppp_stats *st); -static struct ppp *ppp_create_interface(struct net *net, int unit, - struct file *file, int *retp); +static int ppp_create_interface(struct net *net, struct file *file, int *unit); static void init_ppp_file(struct ppp_file *pf, int kind); static void ppp_destroy_interface(struct ppp *ppp); static struct ppp *ppp_find_unit(struct ppp_net *pn, int unit); @@ -853,12 +852,13 @@ static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf, /* Create a new ppp unit */ if (get_user(unit, p)) break; - ppp = ppp_create_interface(net, unit, file, &err); - if (!ppp) + + err = ppp_create_interface(net, file, &unit); + if (err < 0) break; - file->private_data = &ppp->file; + err = -EFAULT; - if (put_user(ppp->file.index, p)) + if (put_user(unit, p)) break; err = 0; break; @@ -2732,8 +2732,7 @@ ppp_get_stats(struct ppp *ppp, struct ppp_stats *st) * or if there is already a unit with the requested number. * unit == -1 means allocate a new number. */ -static struct ppp *ppp_create_interface(struct net *net, int unit, - struct file *file, int *retp) +static int ppp_create_interface(struct net *net, struct file *file, int *unit) { struct ppp *ppp; struct ppp_net *pn; @@ -2776,15 +2775,13 @@ static struct ppp *ppp_create_interface(struct net *net, int unit, rtnl_lock(); mutex_lock(&pn->all_ppp_mutex); - if (unit < 0) { - unit = unit_get(&pn->units_idr, ppp); - if (unit < 0) { - ret = unit; + if (*unit < 0) { + ret = unit_get(&pn->units_idr, ppp); + if (ret < 0) goto out2; - } } else { ret = -EEXIST; - if (unit_find(&pn->units_idr, unit)) + if (unit_find(&pn->units_idr, *unit)) goto out2; /* unit already exists */ /* * if caller need a specified unit number @@ -2795,39 +2792,41 @@ static struct ppp *ppp_create_interface(struct net *net, int unit, * fair but at least pppd will ask us to allocate * new unit in this case so user is happy :) */ - unit = unit_set(&pn->units_idr, ppp, unit); - if (unit < 0) + ret = unit_set(&pn->units_idr, ppp, *unit); + if (ret < 0) { + ret = -EEXIST; goto out2; + } } /* Initialize the new ppp unit */ - ppp->file.index = unit; - sprintf(dev->name, "ppp%d", unit); + ppp->file.index = ret; + sprintf(dev->name, "ppp%d", ret); ret = register_netdevice(dev); if (ret != 0) { - unit_put(&pn->units_idr, unit); + unit_put(&pn->units_idr, ppp->file.index); netdev_err(ppp->dev, "PPP: couldn't register device %s (%d)\n", dev->name, ret); goto out2; } ppp->ppp_net = net; - + file->private_data = &ppp->file; + *unit = ppp->file.index; atomic_inc(&ppp_unit_count); + mutex_unlock(&pn->all_ppp_mutex); rtnl_unlock(); - *retp = 0; - return ppp; + return 0; out2: mutex_unlock(&pn->all_ppp_mutex); rtnl_unlock(); free_netdev(dev); out1: - *retp = ret; - return NULL; + return ret; } /* -- 2.8.0.rc3 -- To unsubscribe from this list: send the line "unsubscribe linux-ppp" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html