9p: Make sure we are able to clunk the cached fid on umount
[safe/jmp/linux-2.6] / net / netlink / af_netlink.c
index d0ff382..acbbae1 100644 (file)
@@ -177,9 +177,11 @@ static void netlink_sock_destruct(struct sock *sk)
  * this, _but_ remember, it adds useless work on UP machines.
  */
 
-static void netlink_table_grab(void)
+void netlink_table_grab(void)
        __acquires(nl_table_lock)
 {
+       might_sleep();
+
        write_lock_irq(&nl_table_lock);
 
        if (atomic_read(&nl_table_users)) {
@@ -200,7 +202,7 @@ static void netlink_table_grab(void)
        }
 }
 
-static void netlink_table_ungrab(void)
+void netlink_table_ungrab(void)
        __releases(nl_table_lock)
 {
        write_unlock_irq(&nl_table_lock);
@@ -426,7 +428,8 @@ static int __netlink_create(struct net *net, struct socket *sock,
        return 0;
 }
 
-static int netlink_create(struct net *net, struct socket *sock, int protocol)
+static int netlink_create(struct net *net, struct socket *sock, int protocol,
+                         int kern)
 {
        struct module *module = NULL;
        struct mutex *cb_mutex;
@@ -452,9 +455,14 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol)
        if (nl_table[protocol].registered &&
            try_module_get(nl_table[protocol].module))
                module = nl_table[protocol].module;
+       else
+               err = -EPROTONOSUPPORT;
        cb_mutex = nl_table[protocol].cb_mutex;
        netlink_unlock_table();
 
+       if (err < 0)
+               goto out;
+
        err = __netlink_create(net, sock, cb_mutex, protocol);
        if (err < 0)
                goto out_module;
@@ -495,7 +503,7 @@ static int netlink_release(struct socket *sock)
 
        skb_queue_purge(&sk->sk_write_queue);
 
-       if (nlk->pid && !nlk->subscriptions) {
+       if (nlk->pid) {
                struct netlink_notify n = {
                                                .net = sock_net(sk),
                                                .protocol = sk->sk_protocol,
@@ -705,7 +713,7 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr,
 {
        struct sock *sk = sock->sk;
        struct netlink_sock *nlk = nlk_sk(sk);
-       struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
+       DECLARE_SOCKADDR(struct sockaddr_nl *, nladdr, addr);
 
        nladdr->nl_family = AF_NETLINK;
        nladdr->nl_pad = 0;
@@ -1085,21 +1093,27 @@ static inline int do_one_set_err(struct sock *sk,
                                 struct netlink_set_err_data *p)
 {
        struct netlink_sock *nlk = nlk_sk(sk);
+       int ret = 0;
 
        if (sk == p->exclude_sk)
                goto out;
 
-       if (sock_net(sk) != sock_net(p->exclude_sk))
+       if (!net_eq(sock_net(sk), sock_net(p->exclude_sk)))
                goto out;
 
        if (nlk->pid == p->pid || p->group - 1 >= nlk->ngroups ||
            !test_bit(p->group - 1, nlk->groups))
                goto out;
 
+       if (p->code == ENOBUFS && nlk->flags & NETLINK_RECV_NO_ENOBUFS) {
+               ret = 1;
+               goto out;
+       }
+
        sk->sk_err = p->code;
        sk->sk_error_report(sk);
 out:
-       return 0;
+       return ret;
 }
 
 /**
@@ -1108,12 +1122,16 @@ out:
  * @pid: the PID of a process that we want to skip (if any)
  * @groups: the broadcast group that will notice the error
  * @code: error code, must be negative (as usual in kernelspace)
+ *
+ * This function returns the number of broadcast listeners that have set the
+ * NETLINK_RECV_NO_ENOBUFS socket option.
  */
-void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
+int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
 {
        struct netlink_set_err_data info;
        struct hlist_node *node;
        struct sock *sk;
+       int ret = 0;
 
        info.exclude_sk = ssk;
        info.pid = pid;
@@ -1124,9 +1142,10 @@ void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
        read_lock(&nl_table_lock);
 
        sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list)
-               do_one_set_err(sk, &info);
+               ret += do_one_set_err(sk, &info);
 
        read_unlock(&nl_table_lock);
+       return ret;
 }
 EXPORT_SYMBOL(netlink_set_err);
 
@@ -1148,7 +1167,7 @@ static void netlink_update_socket_mc(struct netlink_sock *nlk,
 }
 
 static int netlink_setsockopt(struct socket *sock, int level, int optname,
-                             char __user *optval, int optlen)
+                             char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        struct netlink_sock *nlk = nlk_sk(sk);
@@ -1549,37 +1568,21 @@ static void netlink_free_old_listeners(struct rcu_head *rcu_head)
        kfree(lrh->ptr);
 }
 
-/**
- * netlink_change_ngroups - change number of multicast groups
- *
- * This changes the number of multicast groups that are available
- * on a certain netlink family. Note that it is not possible to
- * change the number of groups to below 32. Also note that it does
- * not implicitly call netlink_clear_multicast_users() when the
- * number of groups is reduced.
- *
- * @sk: The kernel netlink socket, as returned by netlink_kernel_create().
- * @groups: The new number of groups.
- */
-int netlink_change_ngroups(struct sock *sk, unsigned int groups)
+int __netlink_change_ngroups(struct sock *sk, unsigned int groups)
 {
        unsigned long *listeners, *old = NULL;
        struct listeners_rcu_head *old_rcu_head;
        struct netlink_table *tbl = &nl_table[sk->sk_protocol];
-       int err = 0;
 
        if (groups < 32)
                groups = 32;
 
-       netlink_table_grab();
        if (NLGRPSZ(tbl->groups) < NLGRPSZ(groups)) {
                listeners = kzalloc(NLGRPSZ(groups) +
                                    sizeof(struct listeners_rcu_head),
                                    GFP_ATOMIC);
-               if (!listeners) {
-                       err = -ENOMEM;
-                       goto out_ungrab;
-               }
+               if (!listeners)
+                       return -ENOMEM;
                old = tbl->listeners;
                memcpy(listeners, old, NLGRPSZ(tbl->groups));
                rcu_assign_pointer(tbl->listeners, listeners);
@@ -1597,11 +1600,42 @@ int netlink_change_ngroups(struct sock *sk, unsigned int groups)
        }
        tbl->groups = groups;
 
- out_ungrab:
+       return 0;
+}
+
+/**
+ * netlink_change_ngroups - change number of multicast groups
+ *
+ * This changes the number of multicast groups that are available
+ * on a certain netlink family. Note that it is not possible to
+ * change the number of groups to below 32. Also note that it does
+ * not implicitly call netlink_clear_multicast_users() when the
+ * number of groups is reduced.
+ *
+ * @sk: The kernel netlink socket, as returned by netlink_kernel_create().
+ * @groups: The new number of groups.
+ */
+int netlink_change_ngroups(struct sock *sk, unsigned int groups)
+{
+       int err;
+
+       netlink_table_grab();
+       err = __netlink_change_ngroups(sk, groups);
        netlink_table_ungrab();
+
        return err;
 }
 
+void __netlink_clear_multicast_users(struct sock *ksk, unsigned int group)
+{
+       struct sock *sk;
+       struct hlist_node *node;
+       struct netlink_table *tbl = &nl_table[ksk->sk_protocol];
+
+       sk_for_each_bound(sk, node, &tbl->mc_list)
+               netlink_update_socket_mc(nlk_sk(sk), group, 0);
+}
+
 /**
  * netlink_clear_multicast_users - kick off multicast listeners
  *
@@ -1612,15 +1646,8 @@ int netlink_change_ngroups(struct sock *sk, unsigned int groups)
  */
 void netlink_clear_multicast_users(struct sock *ksk, unsigned int group)
 {
-       struct sock *sk;
-       struct hlist_node *node;
-       struct netlink_table *tbl = &nl_table[ksk->sk_protocol];
-
        netlink_table_grab();
-
-       sk_for_each_bound(sk, node, &tbl->mc_list)
-               netlink_update_socket_mc(nlk_sk(sk), group, 0);
-
+       __netlink_clear_multicast_users(ksk, group);
        netlink_table_ungrab();
 }
 
@@ -1778,7 +1805,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
        }
 
        rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
-                         NLMSG_ERROR, sizeof(struct nlmsgerr), 0);
+                         NLMSG_ERROR, payload, 0);
        errmsg = nlmsg_data(rep);
        errmsg->error = err;
        memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(*nlh));
@@ -1962,12 +1989,12 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
        if (v == SEQ_START_TOKEN)
                seq_puts(seq,
                         "sk       Eth Pid    Groups   "
-                        "Rmem     Wmem     Dump     Locks     Drops\n");
+                        "Rmem     Wmem     Dump     Locks     Drops     Inode\n");
        else {
                struct sock *s = v;
                struct netlink_sock *nlk = nlk_sk(s);
 
-               seq_printf(seq, "%p %-3d %-6d %08x %-8d %-8d %p %-8d %-8d\n",
+               seq_printf(seq, "%p %-3d %-6d %08x %-8d %-8d %p %-8d %-8d %-8lu\n",
                           s,
                           s->sk_protocol,
                           nlk->pid,
@@ -1976,7 +2003,8 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
                           sk_wmem_alloc_get(s),
                           nlk->cb,
                           atomic_read(&s->sk_refcnt),
-                          atomic_read(&s->sk_drops)
+                          atomic_read(&s->sk_drops),
+                          sock_i_ino(s)
                        );
 
        }
@@ -2040,7 +2068,7 @@ static const struct proto_ops netlink_ops = {
        .sendpage =     sock_no_sendpage,
 };
 
-static struct net_proto_family netlink_family_ops = {
+static const struct net_proto_family netlink_family_ops = {
        .family = PF_NETLINK,
        .create = netlink_create,
        .owner  = THIS_MODULE,  /* for consistency 8) */
@@ -2084,10 +2112,10 @@ static int __init netlink_proto_init(void)
        if (!nl_table)
                goto panic;
 
-       if (num_physpages >= (128 * 1024))
-               limit = num_physpages >> (21 - PAGE_SHIFT);
+       if (totalram_pages >= (128 * 1024))
+               limit = totalram_pages >> (21 - PAGE_SHIFT);
        else
-               limit = num_physpages >> (23 - PAGE_SHIFT);
+               limit = totalram_pages >> (23 - PAGE_SHIFT);
 
        order = get_bitmask_order(limit) - 1 + PAGE_SHIFT;
        limit = (1UL << order) / sizeof(struct hlist_head);