Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 129727
b: refs/heads/master
c: 8599757
h: refs/heads/master
i:
  129725: e80a497
  129723: 8aa420c
  129719: 987e1ac
  129711: 80942f7
  129695: c504d2d
  129663: e391a7c
v: v3
  • Loading branch information
Cyrill Gorcunov authored and David S. Miller committed Jan 13, 2009
1 parent 4fe4a95 commit be525ec
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a6d0b91ae5dd01263530c96f9b29001cb1ed58b0
refs/heads/master: 859975764fa61e927e7a69f46a55a4ba415785dd
43 changes: 37 additions & 6 deletions trunk/drivers/net/ppp_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ static int ppp_connect_channel(struct channel *pch, int unit);
static int ppp_disconnect_channel(struct channel *pch);
static void ppp_destroy_channel(struct channel *pch);
static int unit_get(struct idr *p, void *ptr);
static int unit_set(struct idr *p, void *ptr, int n);
static void unit_put(struct idr *p, int n);
static void *unit_find(struct idr *p, int n);

Expand Down Expand Up @@ -2432,11 +2433,18 @@ ppp_create_interface(int unit, int *retp)
} else {
if (unit_find(&ppp_units_idr, unit))
goto out2; /* unit already exists */
else {
/* darn, someone is cheating us? */
*retp = -EINVAL;
/*
* if caller need a specified unit number
* lets try to satisfy him, otherwise --
* he should better ask us for new unit number
*
* NOTE: yes I know that returning EEXIST it's not
* fair but at least pppd will ask us to allocate
* new unit in this case so user is happy :)
*/
unit = unit_set(&ppp_units_idr, ppp, unit);
if (unit < 0)
goto out2;
}
}

/* Initialize the new ppp unit */
Expand Down Expand Up @@ -2677,14 +2685,37 @@ static void __exit ppp_cleanup(void)
* by holding all_ppp_mutex
*/

/* associate pointer with specified number */
static int unit_set(struct idr *p, void *ptr, int n)
{
int unit, err;

again:
if (!idr_pre_get(p, GFP_KERNEL)) {
printk(KERN_ERR "PPP: No free memory for idr\n");
return -ENOMEM;
}

err = idr_get_new_above(p, ptr, n, &unit);
if (err == -EAGAIN)
goto again;

if (unit != n) {
idr_remove(p, unit);
return -EINVAL;
}

return unit;
}

/* get new free unit number and associate pointer with it */
static int unit_get(struct idr *p, void *ptr)
{
int unit, err;

again:
if (idr_pre_get(p, GFP_KERNEL) == 0) {
printk(KERN_ERR "Out of memory expanding drawable idr\n");
if (!idr_pre_get(p, GFP_KERNEL)) {
printk(KERN_ERR "PPP: No free memory for idr\n");
return -ENOMEM;
}

Expand Down

0 comments on commit be525ec

Please sign in to comment.