|
@@ -2049,7 +2049,7 @@ static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
|
|
|
const struct nft_set *i;
|
|
|
const char *p;
|
|
|
unsigned long *inuse;
|
|
|
- unsigned int n = 0;
|
|
|
+ unsigned int n = 0, min = 0;
|
|
|
|
|
|
p = strnchr(name, IFNAMSIZ, '%');
|
|
|
if (p != NULL) {
|
|
@@ -2059,23 +2059,28 @@ static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
|
|
|
inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL);
|
|
|
if (inuse == NULL)
|
|
|
return -ENOMEM;
|
|
|
-
|
|
|
+cont:
|
|
|
list_for_each_entry(i, &ctx->table->sets, list) {
|
|
|
int tmp;
|
|
|
|
|
|
if (!sscanf(i->name, name, &tmp))
|
|
|
continue;
|
|
|
- if (tmp < 0 || tmp >= BITS_PER_BYTE * PAGE_SIZE)
|
|
|
+ if (tmp < min || tmp >= min + BITS_PER_BYTE * PAGE_SIZE)
|
|
|
continue;
|
|
|
|
|
|
- set_bit(tmp, inuse);
|
|
|
+ set_bit(tmp - min, inuse);
|
|
|
}
|
|
|
|
|
|
n = find_first_zero_bit(inuse, BITS_PER_BYTE * PAGE_SIZE);
|
|
|
+ if (n >= BITS_PER_BYTE * PAGE_SIZE) {
|
|
|
+ min += BITS_PER_BYTE * PAGE_SIZE;
|
|
|
+ memset(inuse, 0, PAGE_SIZE);
|
|
|
+ goto cont;
|
|
|
+ }
|
|
|
free_page((unsigned long)inuse);
|
|
|
}
|
|
|
|
|
|
- snprintf(set->name, sizeof(set->name), name, n);
|
|
|
+ snprintf(set->name, sizeof(set->name), name, min + n);
|
|
|
list_for_each_entry(i, &ctx->table->sets, list) {
|
|
|
if (!strcmp(set->name, i->name))
|
|
|
return -ENFILE;
|