--- dev.c.old Sun Oct 21 15:39:44 2001 +++ dev.c Sun Oct 21 17:45:11 2001 @@ -550,30 +550,65 @@ int dev_alloc_name(struct net_device *dev, const char *name) { - int i; - char buf[32]; + int i, j, k; + char buf[IFNAMSIZ]; char *p; /* * Verify the string as this thing may have come from - * the user. There must be one "%d" and no other "%" + * the user. There may only be one "%d" and no other "%" * characters. */ p = strchr(name, '%'); - if (!p || p[1] != 'd' || strchr(p+2, '%')) + if (!p) + { + snprintf(buf,sizeof(buf),name); + if (__dev_get_by_name(buf) == NULL) { + strcpy(dev->name, buf); + return 0; + } + else + return -ENFILE; + } + + if (p[1] != 'd' || strchr(p+2, '%')) return -EINVAL; /* - * If you need over 100 please also fix the algorithm... + * New algorithm that works in O(log(n)) worst case time, where + * n is the number of already allocated devices with the + * same base name. + * + * The algorithm works by trying a device number j between i and k, + * and changes i and k depending on whether it was allocated or not. + * + * i is the lower bound of already allocated devices, + * k is the upper bound of already allocated devices, + * k = 0 means k is infinite. */ - for (i = 0; i < 100; i++) { - snprintf(buf,sizeof(buf),name,i); + i = j = k = 0; + for (;;) + { + snprintf(buf,sizeof(buf),name,j); if (__dev_get_by_name(buf) == NULL) { - strcpy(dev->name, buf); - return i; + if (j == i || j == i + 1) + { + strcpy(dev->name, buf); + return j; + } + else + k = j; } + else + i = j; + + if (k) + j = (i + k) / 2; + else + j *= 2; + if (j == i) + j++; } - return -ENFILE; /* Over 100 of the things .. bail out! */ } /**