diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2007-09-12 07:48:45 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:49:11 -0400 |
commit | b267b179648e46ea8e2a44f7314a23eb6aee1d6c (patch) | |
tree | f5ad81414be89f41114e2aa63d038fd7eac08c1d | |
parent | 881d966b48b035ab3f3aeaae0f3d3f9b584f45b2 (diff) |
[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>
-rw-r--r-- | net/core/dev.c | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 3a3d5ee73909..520ef7b20862 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -739,9 +739,10 @@ int dev_valid_name(const char *name) | |||
739 | } | 739 | } |
740 | 740 | ||
741 | /** | 741 | /** |
742 | * dev_alloc_name - allocate a name for a device | 742 | * __dev_alloc_name - allocate a name for a device |
743 | * @dev: device | 743 | * @net: network namespace to allocate the device name in |
744 | * @name: name format string | 744 | * @name: name format string |
745 | * @buf: scratch buffer and result name string | ||
745 | * | 746 | * |
746 | * Passed a format string - eg "lt%d" it will try and find a suitable | 747 | * Passed a format string - eg "lt%d" it will try and find a suitable |
747 | * id. It scans list of devices to build up a free map, then chooses | 748 | * 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 | * Returns the number of the unit assigned or a negative errno code. | 753 | * Returns the number of the unit assigned or a negative errno code. |
753 | */ | 754 | */ |
754 | 755 | ||
755 | int dev_alloc_name(struct net_device *dev, const char *name) | 756 | static int __dev_alloc_name(struct net *net, const char *name, char *buf) |
756 | { | 757 | { |
757 | int i = 0; | 758 | int i = 0; |
758 | char buf[IFNAMSIZ]; | ||
759 | const char *p; | 759 | const char *p; |
760 | const int max_netdevices = 8*PAGE_SIZE; | 760 | const int max_netdevices = 8*PAGE_SIZE; |
761 | long *inuse; | 761 | long *inuse; |
762 | struct net_device *d; | 762 | struct net_device *d; |
763 | struct net *net; | ||
764 | |||
765 | BUG_ON(!dev->nd_net); | ||
766 | net = dev->nd_net; | ||
767 | 763 | ||
768 | p = strnchr(name, IFNAMSIZ-1, '%'); | 764 | p = strnchr(name, IFNAMSIZ-1, '%'); |
769 | if (p) { | 765 | if (p) { |
@@ -787,7 +783,7 @@ int dev_alloc_name(struct net_device *dev, const char *name) | |||
787 | continue; | 783 | continue; |
788 | 784 | ||
789 | /* avoid cases where sscanf is not exact inverse of printf */ | 785 | /* avoid cases where sscanf is not exact inverse of printf */ |
790 | snprintf(buf, sizeof(buf), name, i); | 786 | snprintf(buf, IFNAMSIZ, name, i); |
791 | if (!strncmp(buf, d->name, IFNAMSIZ)) | 787 | if (!strncmp(buf, d->name, IFNAMSIZ)) |
792 | set_bit(i, inuse); | 788 | set_bit(i, inuse); |
793 | } | 789 | } |
@@ -796,11 +792,9 @@ int dev_alloc_name(struct net_device *dev, const char *name) | |||
796 | free_page((unsigned long) inuse); | 792 | free_page((unsigned long) inuse); |
797 | } | 793 | } |
798 | 794 | ||
799 | snprintf(buf, sizeof(buf), name, i); | 795 | snprintf(buf, IFNAMSIZ, name, i); |
800 | if (!__dev_get_by_name(net, buf)) { | 796 | if (!__dev_get_by_name(net, buf)) |
801 | strlcpy(dev->name, buf, IFNAMSIZ); | ||
802 | return i; | 797 | return i; |
803 | } | ||
804 | 798 | ||
805 | /* It is possible to run out of possible slots | 799 | /* It is possible to run out of possible slots |
806 | * when the name is long and there isn't enough space left | 800 | * 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 | return -ENFILE; | 803 | return -ENFILE; |
810 | } | 804 | } |
811 | 805 | ||
806 | /** | ||
807 | * dev_alloc_name - allocate a name for a device | ||
808 | * @dev: device | ||
809 | * @name: name format string | ||
810 | * | ||
811 | * Passed a format string - eg "lt%d" it will try and find a suitable | ||
812 | * id. It scans list of devices to build up a free map, then chooses | ||
813 | * the first empty slot. The caller must hold the dev_base or rtnl lock | ||
814 | * while allocating the name and adding the device in order to avoid | ||
815 | * duplicates. | ||
816 | * Limited to bits_per_byte * page size devices (ie 32K on most platforms). | ||
817 | * Returns the number of the unit assigned or a negative errno code. | ||
818 | */ | ||
819 | |||
820 | int dev_alloc_name(struct net_device *dev, const char *name) | ||
821 | { | ||
822 | char buf[IFNAMSIZ]; | ||
823 | struct net *net; | ||
824 | int ret; | ||
825 | |||
826 | BUG_ON(!dev->nd_net); | ||
827 | net = dev->nd_net; | ||
828 | ret = __dev_alloc_name(net, name, buf); | ||
829 | if (ret >= 0) | ||
830 | strlcpy(dev->name, buf, IFNAMSIZ); | ||
831 | return ret; | ||
832 | } | ||
833 | |||
812 | 834 | ||
813 | /** | 835 | /** |
814 | * dev_change_name - change name of a device | 836 | * dev_change_name - change name of a device |