nfsd: nfsd should drop CAP_MKNOD for non-root
[safe/jmp/linux-2.6] / net / rose / rose_route.c
index fb9359f..a81066a 100644 (file)
@@ -662,27 +662,34 @@ struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neig
 }
 
 /*
- *     Find a neighbour given a ROSE address.
+ *     Find a neighbour or a route given a ROSE address.
  */
 struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
-       unsigned char *diagnostic)
+       unsigned char *diagnostic, int new)
 {
        struct rose_neigh *res = NULL;
        struct rose_node *node;
        int failed = 0;
        int i;
 
-       spin_lock_bh(&rose_node_list_lock);
+       if (!new) spin_lock_bh(&rose_node_list_lock);
        for (node = rose_node_list; node != NULL; node = node->next) {
                if (rosecmpm(addr, &node->address, node->mask) == 0) {
                        for (i = 0; i < node->count; i++) {
-                               if (!rose_ftimer_running(node->neighbour[i])) {
-                                       res = node->neighbour[i];
-                                       goto out;
-                               } else
-                                       failed = 1;
+                               if (new) {
+                                       if (node->neighbour[i]->restarted) {
+                                               res = node->neighbour[i];
+                                               goto out;
+                                       }
+                               }
+                               else {
+                                       if (!rose_ftimer_running(node->neighbour[i])) {
+                                               res = node->neighbour[i];
+                                               goto out;
+                                       } else
+                                               failed = 1;
+                               }
                        }
-                       break;
                }
        }
 
@@ -695,7 +702,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
        }
 
 out:
-       spin_unlock_bh(&rose_node_list_lock);
+       if (!new) spin_unlock_bh(&rose_node_list_lock);
 
        return res;
 }
@@ -857,7 +864,6 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
        src_addr  = (rose_address *)(skb->data + 9);
        dest_addr = (rose_address *)(skb->data + 4);
 
-       spin_lock_bh(&rose_node_list_lock);
        spin_lock_bh(&rose_neigh_list_lock);
        spin_lock_bh(&rose_route_list_lock);
 
@@ -1019,7 +1025,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
                rose_route = rose_route->next;
        }
 
-       if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic)) == NULL) {
+       if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic, 1)) == NULL) {
                rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic);
                goto out;
        }
@@ -1060,7 +1066,6 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
 out:
        spin_unlock_bh(&rose_route_list_lock);
        spin_unlock_bh(&rose_neigh_list_lock);
-       spin_unlock_bh(&rose_node_list_lock);
 
        return res;
 }
@@ -1068,12 +1073,12 @@ out:
 #ifdef CONFIG_PROC_FS
 
 static void *rose_node_start(struct seq_file *seq, loff_t *pos)
-       __acquires(rose_neigh_list_lock)
+       __acquires(rose_node_list_lock)
 {
        struct rose_node *rose_node;
        int i = 1;
 
-       spin_lock_bh(&rose_neigh_list_lock);
+       spin_lock_bh(&rose_node_list_lock);
        if (*pos == 0)
                return SEQ_START_TOKEN;
 
@@ -1092,9 +1097,9 @@ static void *rose_node_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void rose_node_stop(struct seq_file *seq, void *v)
-       __releases(rose_neigh_list_lock)
+       __releases(rose_node_list_lock)
 {
-       spin_unlock_bh(&rose_neigh_list_lock);
+       spin_unlock_bh(&rose_node_list_lock);
 }
 
 static int rose_node_show(struct seq_file *seq, void *v)