Merge branch 'master' of ../net-2.6/
authorDavid S. Miller <davem@davemloft.net>
Mon, 24 Mar 2008 05:54:03 +0000 (22:54 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 24 Mar 2008 05:54:03 +0000 (22:54 -0700)
Conflicts:

net/ipv6/ndisc.c

1  2 
include/net/sctp/sctp.h
net/atm/clip.c
net/atm/lec.c
net/ipv4/fib_trie.c
net/ipv4/tcp.c

diff --combined include/net/sctp/sctp.h
@@@ -368,6 -368,11 +368,6 @@@ void sctp_sysctl_unregister(void)
  #else
  static inline void sctp_sysctl_register(void) { return; }
  static inline void sctp_sysctl_unregister(void) { return; }
 -static inline int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
 -              void __user *oldval, size_t __user *oldlenp,
 -              void __user *newval, size_t newlen) {
 -      return -ENOSYS;
 -}
  #endif
  
  /* Size of Supported Address Parameter for 'x' address types. */
@@@ -384,7 -389,7 +384,7 @@@ void sctp_v6_del_protocol(void)
  
  #else /* #ifdef defined(CONFIG_IPV6) */
  
- static inline void sctp_v6_pf_init(void) { return 0; }
+ static inline void sctp_v6_pf_init(void) { return; }
  static inline void sctp_v6_pf_exit(void) { return; }
  static inline int sctp_v6_protosw_init(void) { return 0; }
  static inline void sctp_v6_protosw_exit(void) { return; }
diff --combined net/atm/clip.c
@@@ -648,6 -648,10 +648,6 @@@ static int clip_inet_event(struct notif
        struct in_device *in_dev;
  
        in_dev = ((struct in_ifaddr *)ifa)->ifa_dev;
 -      if (!in_dev || !in_dev->dev) {
 -              printk(KERN_WARNING "clip_inet_event: no device\n");
 -              return NOTIFY_DONE;
 -      }
        /*
         * Transitions are of the down-change-up type, so it's sufficient to
         * handle the change on up.
@@@ -943,6 -947,8 +943,8 @@@ static const struct file_operations arp
  };
  #endif
  
+ static void atm_clip_exit_noproc(void);
  static int __init atm_clip_init(void)
  {
        neigh_table_init_no_netlink(&clip_tbl);
                struct proc_dir_entry *p;
  
                p = proc_create("arp", S_IRUGO, atm_proc_root, &arp_seq_fops);
+               if (!p) {
+                       printk(KERN_ERR "Unable to initialize "
+                              "/proc/net/atm/arp\n");
+                       atm_clip_exit_noproc();
+                       return -ENOMEM;
+               }
        }
  #endif
  
        return 0;
  }
  
- static void __exit atm_clip_exit(void)
+ static void atm_clip_exit_noproc(void)
  {
        struct net_device *dev, *next;
  
-       remove_proc_entry("arp", atm_proc_root);
        unregister_inetaddr_notifier(&clip_inet_notifier);
        unregister_netdevice_notifier(&clip_dev_notifier);
  
        clip_tbl_hook = NULL;
  }
  
+ static void __exit atm_clip_exit(void)
+ {
+       remove_proc_entry("arp", atm_proc_root);
+       atm_clip_exit_noproc();
+ }
  module_init(atm_clip_init);
  module_exit(atm_clip_exit);
  MODULE_AUTHOR("Werner Almesberger");
diff --combined net/atm/lec.c
@@@ -1169,7 -1169,32 +1169,7 @@@ static const struct seq_operations lec_
  
  static int lec_seq_open(struct inode *inode, struct file *file)
  {
 -      struct lec_state *state;
 -      struct seq_file *seq;
 -      int rc = -EAGAIN;
 -
 -      state = kmalloc(sizeof(*state), GFP_KERNEL);
 -      if (!state) {
 -              rc = -ENOMEM;
 -              goto out;
 -      }
 -
 -      rc = seq_open(file, &lec_seq_ops);
 -      if (rc)
 -              goto out_kfree;
 -      seq = file->private_data;
 -      seq->private = state;
 -out:
 -      return rc;
 -
 -out_kfree:
 -      kfree(state);
 -      goto out;
 -}
 -
 -static int lec_seq_release(struct inode *inode, struct file *file)
 -{
 -      return seq_release_private(inode, file);
 +      return seq_open_private(file, &lec_seq_ops, sizeof(struct lec_state));
  }
  
  static const struct file_operations lec_seq_fops = {
        .open = lec_seq_open,
        .read = seq_read,
        .llseek = seq_lseek,
 -      .release = lec_seq_release,
 +      .release = seq_release_private,
  };
  #endif
  
@@@ -1225,6 -1250,10 +1225,10 @@@ static int __init lane_module_init(void
        struct proc_dir_entry *p;
  
        p = proc_create("lec", S_IRUGO, atm_proc_root, &lec_seq_fops);
+       if (!p) {
+               printk(KERN_ERR "Unable to initialize /proc/net/atm/lec\n");
+               return -ENOMEM;
+       }
  #endif
  
        register_atm_ioctl(&lane_ioctl_ops);
diff --combined net/ipv4/fib_trie.c
@@@ -177,10 -177,13 +177,13 @@@ static inline struct tnode *node_parent
        return rcu_dereference(ret);
  }
  
+ /* Same as rcu_assign_pointer
+  * but that macro() assumes that value is a pointer.
+  */
  static inline void node_set_parent(struct node *node, struct tnode *ptr)
  {
-       rcu_assign_pointer(node->parent,
-                          (unsigned long)ptr | NODE_TYPE(node));
+       smp_wmb();
+       node->parent = (unsigned long)ptr | NODE_TYPE(node);
  }
  
  static inline struct node *tnode_get_child(struct tnode *tn, unsigned int i)
@@@ -2026,8 -2029,9 +2029,8 @@@ struct fib_table *fib_hash_table(u32 id
  /* Depth first Trie walk iterator */
  struct fib_trie_iter {
        struct seq_net_private p;
 -      struct trie *trie_local, *trie_main;
 +      struct fib_table *tb;
        struct tnode *tnode;
 -      struct trie *trie;
        unsigned index;
        unsigned depth;
  };
@@@ -2080,26 -2084,31 +2083,26 @@@ rescan
  static struct node *fib_trie_get_first(struct fib_trie_iter *iter,
                                       struct trie *t)
  {
 -      struct node *n ;
 +      struct node *n;
  
        if (!t)
                return NULL;
  
        n = rcu_dereference(t->trie);
 -
 -      if (!iter)
 +      if (!n)
                return NULL;
  
 -      if (n) {
 -              if (IS_TNODE(n)) {
 -                      iter->tnode = (struct tnode *) n;
 -                      iter->trie = t;
 -                      iter->index = 0;
 -                      iter->depth = 1;
 -              } else {
 -                      iter->tnode = NULL;
 -                      iter->trie  = t;
 -                      iter->index = 0;
 -                      iter->depth = 0;
 -              }
 -              return n;
 +      if (IS_TNODE(n)) {
 +              iter->tnode = (struct tnode *) n;
 +              iter->index = 0;
 +              iter->depth = 1;
 +      } else {
 +              iter->tnode = NULL;
 +              iter->index = 0;
 +              iter->depth = 0;
        }
 -      return NULL;
 +
 +      return n;
  }
  
  static void trie_collect_stats(struct trie *t, struct trie_stat *s)
        memset(s, 0, sizeof(*s));
  
        rcu_read_lock();
 -      for (n = fib_trie_get_first(&iter, t); n;
 -           n = fib_trie_get_next(&iter)) {
 +      for (n = fib_trie_get_first(&iter, t); n; n = fib_trie_get_next(&iter)) {
                if (IS_LEAF(n)) {
                        struct leaf *l = (struct leaf *)n;
                        struct leaf_info *li;
@@@ -2199,48 -2209,36 +2202,48 @@@ static void trie_show_usage(struct seq_
  }
  #endif /*  CONFIG_IP_FIB_TRIE_STATS */
  
 -static void fib_trie_show(struct seq_file *seq, const char *name,
 -                        struct trie *trie)
 +static void fib_table_print(struct seq_file *seq, struct fib_table *tb)
  {
 -      struct trie_stat stat;
 -
 -      trie_collect_stats(trie, &stat);
 -      seq_printf(seq, "%s:\n", name);
 -      trie_show_stats(seq, &stat);
 -#ifdef CONFIG_IP_FIB_TRIE_STATS
 -      trie_show_usage(seq, &trie->stats);
 -#endif
 +      if (tb->tb_id == RT_TABLE_LOCAL)
 +              seq_puts(seq, "Local:\n");
 +      else if (tb->tb_id == RT_TABLE_MAIN)
 +              seq_puts(seq, "Main:\n");
 +      else
 +              seq_printf(seq, "Id %d:\n", tb->tb_id);
  }
  
 +
  static int fib_triestat_seq_show(struct seq_file *seq, void *v)
  {
        struct net *net = (struct net *)seq->private;
 -      struct fib_table *tb;
 +      unsigned int h;
  
        seq_printf(seq,
                   "Basic info: size of leaf:"
                   " %Zd bytes, size of tnode: %Zd bytes.\n",
                   sizeof(struct leaf), sizeof(struct tnode));
  
 -      tb = fib_get_table(net, RT_TABLE_LOCAL);
 -      if (tb)
 -              fib_trie_show(seq, "Local", (struct trie *) tb->tb_data);
 +      for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
 +              struct hlist_head *head = &net->ipv4.fib_table_hash[h];
 +              struct hlist_node *node;
 +              struct fib_table *tb;
 +
 +              hlist_for_each_entry_rcu(tb, node, head, tb_hlist) {
 +                      struct trie *t = (struct trie *) tb->tb_data;
 +                      struct trie_stat stat;
  
 -      tb = fib_get_table(net, RT_TABLE_MAIN);
 -      if (tb)
 -              fib_trie_show(seq, "Main", (struct trie *) tb->tb_data);
 +                      if (!t)
 +                              continue;
 +
 +                      fib_table_print(seq, tb);
 +
 +                      trie_collect_stats(t, &stat);
 +                      trie_show_stats(seq, &stat);
 +#ifdef CONFIG_IP_FIB_TRIE_STATS
 +                      trie_show_usage(seq, &t->stats);
 +#endif
 +              }
 +      }
  
        return 0;
  }
@@@ -2276,30 -2274,23 +2279,30 @@@ static const struct file_operations fib
        .release = fib_triestat_seq_release,
  };
  
 -static struct node *fib_trie_get_idx(struct fib_trie_iter *iter,
 -                                    loff_t pos)
 +static struct node *fib_trie_get_idx(struct fib_trie_iter *iter, loff_t pos)
  {
 +      struct net *net = iter->p.net;
        loff_t idx = 0;
 -      struct node *n;
 +      unsigned int h;
  
 -      for (n = fib_trie_get_first(iter, iter->trie_local);
 -           n; ++idx, n = fib_trie_get_next(iter)) {
 -              if (pos == idx)
 -                      return n;
 -      }
 +      for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
 +              struct hlist_head *head = &net->ipv4.fib_table_hash[h];
 +              struct hlist_node *node;
 +              struct fib_table *tb;
  
 -      for (n = fib_trie_get_first(iter, iter->trie_main);
 -           n; ++idx, n = fib_trie_get_next(iter)) {
 -              if (pos == idx)
 -                      return n;
 +              hlist_for_each_entry_rcu(tb, node, head, tb_hlist) {
 +                      struct node *n;
 +
 +                      for (n = fib_trie_get_first(iter,
 +                                                  (struct trie *) tb->tb_data);
 +                           n; n = fib_trie_get_next(iter))
 +                              if (pos == idx++) {
 +                                      iter->tb = tb;
 +                                      return n;
 +                              }
 +              }
        }
 +
        return NULL;
  }
  
@@@ -2307,49 -2298,43 +2310,49 @@@ static void *fib_trie_seq_start(struct 
        __acquires(RCU)
  {
        struct fib_trie_iter *iter = seq->private;
 -      struct fib_table *tb;
  
 -      if (!iter->trie_local) {
 -              tb = fib_get_table(iter->p.net, RT_TABLE_LOCAL);
 -              if (tb)
 -                      iter->trie_local = (struct trie *) tb->tb_data;
 -      }
 -      if (!iter->trie_main) {
 -              tb = fib_get_table(iter->p.net, RT_TABLE_MAIN);
 -              if (tb)
 -                      iter->trie_main = (struct trie *) tb->tb_data;
 -      }
        rcu_read_lock();
 -      if (*pos == 0)
 -              return SEQ_START_TOKEN;
 -      return fib_trie_get_idx(iter, *pos - 1);
 +      return fib_trie_get_idx(iter, *pos);
  }
  
  static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  {
        struct fib_trie_iter *iter = seq->private;
 -      void *l = v;
 +      struct net *net = iter->p.net;
 +      struct fib_table *tb = iter->tb;
 +      struct hlist_node *tb_node;
 +      unsigned int h;
 +      struct node *n;
  
        ++*pos;
 -      if (v == SEQ_START_TOKEN)
 -              return fib_trie_get_idx(iter, 0);
 -
 -      v = fib_trie_get_next(iter);
 -      BUG_ON(v == l);
 -      if (v)
 -              return v;
 +      /* next node in same table */
 +      n = fib_trie_get_next(iter);
 +      if (n)
 +              return n;
  
 -      /* continue scan in next trie */
 -      if (iter->trie == iter->trie_local)
 -              return fib_trie_get_first(iter, iter->trie_main);
 +      /* walk rest of this hash chain */
 +      h = tb->tb_id & (FIB_TABLE_HASHSZ - 1);
 +      while ( (tb_node = rcu_dereference(tb->tb_hlist.next)) ) {
 +              tb = hlist_entry(tb_node, struct fib_table, tb_hlist);
 +              n = fib_trie_get_first(iter, (struct trie *) tb->tb_data);
 +              if (n)
 +                      goto found;
 +      }
  
 +      /* new hash chain */
 +      while (++h < FIB_TABLE_HASHSZ) {
 +              struct hlist_head *head = &net->ipv4.fib_table_hash[h];
 +              hlist_for_each_entry_rcu(tb, tb_node, head, tb_hlist) {
 +                      n = fib_trie_get_first(iter, (struct trie *) tb->tb_data);
 +                      if (n)
 +                              goto found;
 +              }
 +      }
        return NULL;
 +
 +found:
 +      iter->tb = tb;
 +      return n;
  }
  
  static void fib_trie_seq_stop(struct seq_file *seq, void *v)
@@@ -2406,8 -2391,15 +2409,8 @@@ static int fib_trie_seq_show(struct seq
        const struct fib_trie_iter *iter = seq->private;
        struct node *n = v;
  
 -      if (v == SEQ_START_TOKEN)
 -              return 0;
 -
 -      if (!node_parent_rcu(n)) {
 -              if (iter->trie == iter->trie_local)
 -                      seq_puts(seq, "<local>:\n");
 -              else
 -                      seq_puts(seq, "<main>:\n");
 -      }
 +      if (!node_parent_rcu(n))
 +              fib_table_print(seq, iter->tb);
  
        if (IS_TNODE(n)) {
                struct tnode *tn = (struct tnode *) n;
diff --combined net/ipv4/tcp.c
@@@ -735,7 -735,7 +735,7 @@@ new_segment
                if (!(psize -= copy))
                        goto out;
  
-               if (skb->len < mss_now || (flags & MSG_OOB))
+               if (skb->len < size_goal || (flags & MSG_OOB))
                        continue;
  
                if (forced_push(tp)) {
@@@ -981,7 -981,7 +981,7 @@@ new_segment
                        if ((seglen -= copy) == 0 && iovlen == 0)
                                goto out;
  
-                       if (skb->len < mss_now || (flags & MSG_OOB))
+                       if (skb->len < size_goal || (flags & MSG_OOB))
                                continue;
  
                        if (forced_push(tp)) {
@@@ -2105,12 -2105,15 +2105,12 @@@ static int do_tcp_setsockopt(struct soc
                break;
  
        case TCP_DEFER_ACCEPT:
 -              icsk->icsk_accept_queue.rskq_defer_accept = 0;
 -              if (val > 0) {
 -                      /* Translate value in seconds to number of
 -                       * retransmits */
 -                      while (icsk->icsk_accept_queue.rskq_defer_accept < 32 &&
 -                             val > ((TCP_TIMEOUT_INIT / HZ) <<
 -                                     icsk->icsk_accept_queue.rskq_defer_accept))
 -                              icsk->icsk_accept_queue.rskq_defer_accept++;
 -                      icsk->icsk_accept_queue.rskq_defer_accept++;
 +              if (val < 0) {
 +                      err = -EINVAL;
 +              } else {
 +                      if (val > MAX_TCP_ACCEPT_DEFERRED)
 +                              val = MAX_TCP_ACCEPT_DEFERRED;
 +                      icsk->icsk_accept_queue.rskq_defer_accept = val;
                }
                break;
  
@@@ -2292,7 -2295,8 +2292,7 @@@ static int do_tcp_getsockopt(struct soc
                        val = (val ? : sysctl_tcp_fin_timeout) / HZ;
                break;
        case TCP_DEFER_ACCEPT:
 -              val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 :
 -                      ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1));
 +              val = icsk->icsk_accept_queue.rskq_defer_accept;
                break;
        case TCP_WINDOW_CLAMP:
                val = tp->window_clamp;