[NET]: Factor out __dev_alloc_name from dev_alloc_name
When forcibly changing the network namespace of a device I need something that can generate a name for the device in the new namespace without overwriting the old name. __dev_alloc_name provides me that functionality. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
881d966b48
commit
b267b17964
@@ -739,9 +739,10 @@ int dev_valid_name(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dev_alloc_name - allocate a name for a device
|
* __dev_alloc_name - allocate a name for a device
|
||||||
* @dev: device
|
* @net: network namespace to allocate the device name in
|
||||||
* @name: name format string
|
* @name: name format string
|
||||||
|
* @buf: scratch buffer and result name string
|
||||||
*
|
*
|
||||||
* Passed a format string - eg "lt%d" it will try and find a suitable
|
* Passed a format string - eg "lt%d" it will try and find a suitable
|
||||||
* id. It scans list of devices to build up a free map, then chooses
|
* id. It scans list of devices to build up a free map, then chooses
|
||||||
@@ -752,18 +753,13 @@ int dev_valid_name(const char *name)
|
|||||||
* Returns the number of the unit assigned or a negative errno code.
|
* Returns the number of the unit assigned or a negative errno code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int dev_alloc_name(struct net_device *dev, const char *name)
|
static int __dev_alloc_name(struct net *net, const char *name, char *buf)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
char buf[IFNAMSIZ];
|
|
||||||
const char *p;
|
const char *p;
|
||||||
const int max_netdevices = 8*PAGE_SIZE;
|
const int max_netdevices = 8*PAGE_SIZE;
|
||||||
long *inuse;
|
long *inuse;
|
||||||
struct net_device *d;
|
struct net_device *d;
|
||||||
struct net *net;
|
|
||||||
|
|
||||||
BUG_ON(!dev->nd_net);
|
|
||||||
net = dev->nd_net;
|
|
||||||
|
|
||||||
p = strnchr(name, IFNAMSIZ-1, '%');
|
p = strnchr(name, IFNAMSIZ-1, '%');
|
||||||
if (p) {
|
if (p) {
|
||||||
@@ -787,7 +783,7 @@ int dev_alloc_name(struct net_device *dev, const char *name)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* avoid cases where sscanf is not exact inverse of printf */
|
/* avoid cases where sscanf is not exact inverse of printf */
|
||||||
snprintf(buf, sizeof(buf), name, i);
|
snprintf(buf, IFNAMSIZ, name, i);
|
||||||
if (!strncmp(buf, d->name, IFNAMSIZ))
|
if (!strncmp(buf, d->name, IFNAMSIZ))
|
||||||
set_bit(i, inuse);
|
set_bit(i, inuse);
|
||||||
}
|
}
|
||||||
@@ -796,11 +792,9 @@ int dev_alloc_name(struct net_device *dev, const char *name)
|
|||||||
free_page((unsigned long) inuse);
|
free_page((unsigned long) inuse);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), name, i);
|
snprintf(buf, IFNAMSIZ, name, i);
|
||||||
if (!__dev_get_by_name(net, buf)) {
|
if (!__dev_get_by_name(net, buf))
|
||||||
strlcpy(dev->name, buf, IFNAMSIZ);
|
|
||||||
return i;
|
return i;
|
||||||
}
|
|
||||||
|
|
||||||
/* It is possible to run out of possible slots
|
/* It is possible to run out of possible slots
|
||||||
* when the name is long and there isn't enough space left
|
* when the name is long and there isn't enough space left
|
||||||
@@ -809,6 +803,34 @@ int dev_alloc_name(struct net_device *dev, const char *name)
|
|||||||
return -ENFILE;
|
return -ENFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dev_alloc_name - allocate a name for a device
|
||||||
|
* @dev: device
|
||||||
|
* @name: name format string
|
||||||
|
*
|
||||||
|
* Passed a format string - eg "lt%d" it will try and find a suitable
|
||||||
|
* id. It scans list of devices to build up a free map, then chooses
|
||||||
|
* the first empty slot. The caller must hold the dev_base or rtnl lock
|
||||||
|
* while allocating the name and adding the device in order to avoid
|
||||||
|
* duplicates.
|
||||||
|
* Limited to bits_per_byte * page size devices (ie 32K on most platforms).
|
||||||
|
* Returns the number of the unit assigned or a negative errno code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int dev_alloc_name(struct net_device *dev, const char *name)
|
||||||
|
{
|
||||||
|
char buf[IFNAMSIZ];
|
||||||
|
struct net *net;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
BUG_ON(!dev->nd_net);
|
||||||
|
net = dev->nd_net;
|
||||||
|
ret = __dev_alloc_name(net, name, buf);
|
||||||
|
if (ret >= 0)
|
||||||
|
strlcpy(dev->name, buf, IFNAMSIZ);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dev_change_name - change name of a device
|
* dev_change_name - change name of a device
|
||||||
|
Reference in New Issue
Block a user