[PATCH] uml: add locking to network transport registration
authorJeff Dike <jdike@addtoit.com>
Sat, 10 Feb 2007 09:43:56 +0000 (01:43 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sun, 11 Feb 2007 18:51:21 +0000 (10:51 -0800)
The registration of host network transports needed some locking.  The
transport list itself is locked, but calls to the registration routines are
not.  This is compensated for by checking that a transport structure is not
yet on any list.

I also took the opportunity to const all fields in the transport structure
except the list, which obviously can be modified.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/um/drivers/net_kern.c
arch/um/include/net_kern.h

index 07e839e387dbe51e32e0f1faa318ebb68f08cb69..b10154cc46b67b675d4e44cdaca4f0661ccc0690 100644 (file)
@@ -498,10 +498,8 @@ struct eth_init {
        int index;
 };
 
-/* Filled in at boot time.  Will need locking if the transports become
- * modular.
- */
-struct list_head transports = LIST_HEAD_INIT(transports);
+static DEFINE_SPINLOCK(transports_lock);
+static LIST_HEAD(transports);
 
 /* Filled in during early boot */
 struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
@@ -540,7 +538,10 @@ void register_transport(struct transport *new)
        char *mac = NULL;
        int match;
 
+       spin_lock(&transports_lock);
+       BUG_ON(!list_empty(&new->list));
        list_add(&new->list, &transports);
+       spin_unlock(&transports_lock);
 
        list_for_each_safe(ele, next, &eth_cmd_line){
                eth = list_entry(ele, struct eth_init, list);
index 218f8b47fdcd7ea80543acca85bc4e2b0bd9e972..92f76d82a6ef2e141a456d801702cef603c46f4b 100644 (file)
@@ -52,12 +52,12 @@ struct net_kern_info {
 
 struct transport {
        struct list_head list;
-       char *name;
-       int (*setup)(char *, char **, void *);
+       const char *name;
+       int (* const setup)(char *, char **, void *);
        const struct net_user_info *user;
        const struct net_kern_info *kern;
-       int private_size;
-       int setup_size;
+       const int private_size;
+       const int setup_size;
 };
 
 extern struct net_device *ether_init(int);