Commit b267b179 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by David S. Miller

[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: default avatarEric W. Biederman <ebiederm@xmission.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 881d966b
...@@ -739,9 +739,10 @@ int dev_valid_name(const char *name) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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
......
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