Commit 2f80b3c8 authored by Robert Olsson's avatar Robert Olsson Committed by David S. Miller

[IPV4]: fib_trie: Use ERR_PTR to handle errno return

Signed-off-by: default avatarRobert Olsson <robert.olsson@its.uu.se>
Signed-off-by: default avatarStephen Hemminger <shemminger@osdl.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 91b9a277
...@@ -167,8 +167,8 @@ static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n); ...@@ -167,8 +167,8 @@ static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n);
static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull); static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull);
static int tnode_child_length(struct tnode *tn); static int tnode_child_length(struct tnode *tn);
static struct node *resize(struct trie *t, struct tnode *tn); static struct node *resize(struct trie *t, struct tnode *tn);
static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err); static struct tnode *inflate(struct trie *t, struct tnode *tn);
static struct tnode *halve(struct trie *t, struct tnode *tn, int *err); static struct tnode *halve(struct trie *t, struct tnode *tn);
static void tnode_free(struct tnode *tn); static void tnode_free(struct tnode *tn);
static void trie_dump_seq(struct seq_file *seq, struct trie *t); static void trie_dump_seq(struct seq_file *seq, struct trie *t);
extern struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio); extern struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio);
...@@ -457,6 +457,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) ...@@ -457,6 +457,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
{ {
int i; int i;
int err = 0; int err = 0;
struct tnode *old_tn;
if (!tn) if (!tn)
return NULL; return NULL;
...@@ -559,9 +560,10 @@ static struct node *resize(struct trie *t, struct tnode *tn) ...@@ -559,9 +560,10 @@ static struct node *resize(struct trie *t, struct tnode *tn)
50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >= 50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >=
inflate_threshold * tnode_child_length(tn))) { inflate_threshold * tnode_child_length(tn))) {
tn = inflate(t, tn, &err); old_tn = tn;
tn = inflate(t, tn);
if (err) { if (IS_ERR(tn)) {
tn = old_tn;
#ifdef CONFIG_IP_FIB_TRIE_STATS #ifdef CONFIG_IP_FIB_TRIE_STATS
t->stats.resize_node_skipped++; t->stats.resize_node_skipped++;
#endif #endif
...@@ -581,9 +583,10 @@ static struct node *resize(struct trie *t, struct tnode *tn) ...@@ -581,9 +583,10 @@ static struct node *resize(struct trie *t, struct tnode *tn)
100 * (tnode_child_length(tn) - tn->empty_children) < 100 * (tnode_child_length(tn) - tn->empty_children) <
halve_threshold * tnode_child_length(tn)) { halve_threshold * tnode_child_length(tn)) {
tn = halve(t, tn, &err); old_tn = tn;
tn = halve(t, tn);
if (err) { if (IS_ERR(tn)) {
tn = old_tn;
#ifdef CONFIG_IP_FIB_TRIE_STATS #ifdef CONFIG_IP_FIB_TRIE_STATS
t->stats.resize_node_skipped++; t->stats.resize_node_skipped++;
#endif #endif
...@@ -618,7 +621,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) ...@@ -618,7 +621,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
return (struct node *) tn; return (struct node *) tn;
} }
static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err) static struct tnode *inflate(struct trie *t, struct tnode *tn)
{ {
struct tnode *inode; struct tnode *inode;
struct tnode *oldtnode = tn; struct tnode *oldtnode = tn;
...@@ -629,10 +632,8 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err) ...@@ -629,10 +632,8 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1); tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1);
if (!tn) { if (!tn)
*err = -ENOMEM; return ERR_PTR(-ENOMEM);
return oldtnode;
}
/* /*
* Preallocate and store tnodes before the actual work so we * Preallocate and store tnodes before the actual work so we
...@@ -653,39 +654,22 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err) ...@@ -653,39 +654,22 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
left = tnode_new(inode->key&(~m), inode->pos + 1, left = tnode_new(inode->key&(~m), inode->pos + 1,
inode->bits - 1); inode->bits - 1);
if (!left)
if (!left) { goto nomem;
*err = -ENOMEM;
break;
}
right = tnode_new(inode->key|m, inode->pos + 1, right = tnode_new(inode->key|m, inode->pos + 1,
inode->bits - 1); inode->bits - 1);
if (!right) { if (!right) {
*err = -ENOMEM; tnode_free(left);
break; goto nomem;
} }
put_child(t, tn, 2*i, (struct node *) left); put_child(t, tn, 2*i, (struct node *) left);
put_child(t, tn, 2*i+1, (struct node *) right); put_child(t, tn, 2*i+1, (struct node *) right);
} }
} }
if (*err) {
int size = tnode_child_length(tn);
int j;
for (j = 0; j < size; j++)
if (tn->child[j])
tnode_free((struct tnode *)tn->child[j]);
tnode_free(tn);
*err = -ENOMEM;
return oldtnode;
}
for (i = 0; i < olen; i++) { for (i = 0; i < olen; i++) {
struct node *node = tnode_get_child(oldtnode, i); struct node *node = tnode_get_child(oldtnode, i);
struct tnode *left, *right; struct tnode *left, *right;
...@@ -763,9 +747,22 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err) ...@@ -763,9 +747,22 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
} }
tnode_free(oldtnode); tnode_free(oldtnode);
return tn; return tn;
nomem:
{
int size = tnode_child_length(tn);
int j;
for(j = 0; j < size; j++)
if (tn->child[j])
tnode_free((struct tnode *)tn->child[j]);
tnode_free(tn);
return ERR_PTR(-ENOMEM);
}
} }
static struct tnode *halve(struct trie *t, struct tnode *tn, int *err) static struct tnode *halve(struct trie *t, struct tnode *tn)
{ {
struct tnode *oldtnode = tn; struct tnode *oldtnode = tn;
struct node *left, *right; struct node *left, *right;
...@@ -776,10 +773,8 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err) ...@@ -776,10 +773,8 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1); tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1);
if (!tn) { if (!tn)
*err = -ENOMEM; return ERR_PTR(-ENOMEM);
return oldtnode;
}
/* /*
* Preallocate and store tnodes before the actual work so we * Preallocate and store tnodes before the actual work so we
...@@ -794,29 +789,16 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err) ...@@ -794,29 +789,16 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
/* Two nonempty children */ /* Two nonempty children */
if (left && right) { if (left && right) {
struct tnode *newBinNode = struct tnode *newn;
tnode_new(left->key, tn->pos + tn->bits, 1);
newn = tnode_new(left->key, tn->pos + tn->bits, 1);
if (!newBinNode) {
*err = -ENOMEM; if (!newn)
break; goto nomem;
}
put_child(t, tn, i/2, (struct node *)newBinNode); put_child(t, tn, i/2, (struct node *)newn);
} }
}
if (*err) {
int size = tnode_child_length(tn);
int j;
for (j = 0; j < size; j++)
if (tn->child[j])
tnode_free((struct tnode *)tn->child[j]);
tnode_free(tn);
*err = -ENOMEM;
return oldtnode;
} }
for (i = 0; i < olen; i += 2) { for (i = 0; i < olen; i += 2) {
...@@ -850,6 +832,19 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err) ...@@ -850,6 +832,19 @@ static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
} }
tnode_free(oldtnode); tnode_free(oldtnode);
return tn; return tn;
nomem:
{
int size = tnode_child_length(tn);
int j;
for(j = 0; j < size; j++)
if (tn->child[j])
tnode_free((struct tnode *)tn->child[j]);
tnode_free(tn);
return ERR_PTR(-ENOMEM);
}
} }
static void trie_init(struct trie *t) static void trie_init(struct trie *t)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment