drm/drm_crtc: return -EFAULT on copy_to_user errors
[safe/jmp/linux-2.6] / net / llc / llc_proc.c
index cb34bc0..7af1ff2 100644 (file)
 
 static void llc_ui_format_mac(struct seq_file *seq, u8 *addr)
 {
-       DECLARE_MAC_BUF(mac);
-       seq_printf(seq, "%s", print_mac(mac, addr));
+       seq_printf(seq, "%pM", addr);
 }
 
 static struct sock *llc_get_sk_idx(loff_t pos)
 {
-       struct list_head *sap_entry;
        struct llc_sap *sap;
-       struct hlist_node *node;
        struct sock *sk = NULL;
-
-       list_for_each(sap_entry, &llc_sap_list) {
-               sap = list_entry(sap_entry, struct llc_sap, node);
-
-               read_lock_bh(&sap->sk_list.lock);
-               sk_for_each(sk, node, &sap->sk_list.list) {
-                       if (!pos)
-                               goto found;
-                       --pos;
+       int i;
+
+       list_for_each_entry_rcu(sap, &llc_sap_list, node) {
+               spin_lock_bh(&sap->sk_lock);
+               for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++) {
+                       struct hlist_nulls_head *head = &sap->sk_laddr_hash[i];
+                       struct hlist_nulls_node *node;
+
+                       sk_nulls_for_each(sk, node, head) {
+                               if (!pos)
+                                       goto found; /* keep the lock */
+                               --pos;
+                       }
                }
-               read_unlock_bh(&sap->sk_list.lock);
+               spin_unlock_bh(&sap->sk_lock);
        }
        sk = NULL;
 found:
@@ -58,10 +59,23 @@ static void *llc_seq_start(struct seq_file *seq, loff_t *pos)
 {
        loff_t l = *pos;
 
-       read_lock_bh(&llc_sap_list_lock);
+       rcu_read_lock_bh();
        return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN;
 }
 
+static struct sock *laddr_hash_next(struct llc_sap *sap, int bucket)
+{
+       struct hlist_nulls_node *node;
+       struct sock *sk = NULL;
+
+       while (++bucket < LLC_SK_LADDR_HASH_ENTRIES)
+               sk_nulls_for_each(sk, node, &sap->sk_laddr_hash[bucket])
+                       goto out;
+
+out:
+       return sk;
+}
+
 static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
        struct sock* sk, *next;
@@ -74,25 +88,23 @@ static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
                goto out;
        }
        sk = v;
-       next = sk_next(sk);
+       next = sk_nulls_next(sk);
        if (next) {
                sk = next;
                goto out;
        }
        llc = llc_sk(sk);
        sap = llc->sap;
-       read_unlock_bh(&sap->sk_list.lock);
-       sk = NULL;
-       for (;;) {
-               if (sap->node.next == &llc_sap_list)
-                       break;
-               sap = list_entry(sap->node.next, struct llc_sap, node);
-               read_lock_bh(&sap->sk_list.lock);
-               if (!hlist_empty(&sap->sk_list.list)) {
-                       sk = sk_head(&sap->sk_list.list);
-                       break;
-               }
-               read_unlock_bh(&sap->sk_list.lock);
+       sk = laddr_hash_next(sap, llc_sk_laddr_hashfn(sap, &llc->laddr));
+       if (sk)
+               goto out;
+       spin_unlock_bh(&sap->sk_lock);
+       list_for_each_entry_continue_rcu(sap, &llc_sap_list, node) {
+               spin_lock_bh(&sap->sk_lock);
+               sk = laddr_hash_next(sap, -1);
+               if (sk)
+                       break; /* keep the lock */
+               spin_unlock_bh(&sap->sk_lock);
        }
 out:
        return sk;
@@ -105,9 +117,9 @@ static void llc_seq_stop(struct seq_file *seq, void *v)
                struct llc_sock *llc = llc_sk(sk);
                struct llc_sap *sap = llc->sap;
 
-               read_unlock_bh(&sap->sk_list.lock);
+               spin_unlock_bh(&sap->sk_lock);
        }
-       read_unlock_bh(&llc_sap_list_lock);
+       rcu_read_unlock_bh();
 }
 
 static int llc_seq_socket_show(struct seq_file *seq, void *v)
@@ -135,8 +147,8 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v)
        seq_printf(seq, "@%02X ", llc->sap->laddr.lsap);
        llc_ui_format_mac(seq, llc->daddr.mac);
        seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap,
-                  atomic_read(&sk->sk_wmem_alloc),
-                  atomic_read(&sk->sk_rmem_alloc) - llc->copied_seq,
+                  sk_wmem_alloc_get(sk),
+                  sk_rmem_alloc_get(sk) - llc->copied_seq,
                   sk->sk_state,
                   sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1,
                   llc->link);
@@ -144,7 +156,7 @@ out:
        return 0;
 }
 
-static char *llc_conn_state_names[] = {
+static const char *const llc_conn_state_names[] = {
        [LLC_CONN_STATE_ADM] =        "adm",
        [LLC_CONN_STATE_SETUP] =      "setup",
        [LLC_CONN_STATE_NORMAL] =     "normal",
@@ -237,20 +249,15 @@ int __init llc_proc_init(void)
        llc_proc_dir = proc_mkdir("llc", init_net.proc_net);
        if (!llc_proc_dir)
                goto out;
-       llc_proc_dir->owner = THIS_MODULE;
 
-       p = create_proc_entry("socket", S_IRUGO, llc_proc_dir);
+       p = proc_create("socket", S_IRUGO, llc_proc_dir, &llc_seq_socket_fops);
        if (!p)
                goto out_socket;
 
-       p->proc_fops = &llc_seq_socket_fops;
-
-       p = create_proc_entry("core", S_IRUGO, llc_proc_dir);
+       p = proc_create("core", S_IRUGO, llc_proc_dir, &llc_seq_core_fops);
        if (!p)
                goto out_core;
 
-       p->proc_fops = &llc_seq_core_fops;
-
        rc = 0;
 out:
        return rc;