nfsd4: simplify lease/grace interaction
[safe/jmp/linux-2.6] / net / decnet / af_decnet.c
index aca4c49..2b494fa 100644 (file)
@@ -157,7 +157,7 @@ static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
 static struct hlist_head dn_wild_sk;
 static atomic_t decnet_memory_allocated;
 
-static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen, int flags);
+static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags);
 static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
 
 static struct hlist_head *dn_find_list(struct sock *sk)
@@ -167,7 +167,7 @@ static struct hlist_head *dn_find_list(struct sock *sk)
        if (scp->addr.sdn_flags & SDF_WILD)
                return hlist_empty(&dn_wild_sk) ? &dn_wild_sk : NULL;
 
-       return &dn_sk_hash[dn_ntohs(scp->addrloc) & DN_SK_HASH_MASK];
+       return &dn_sk_hash[le16_to_cpu(scp->addrloc) & DN_SK_HASH_MASK];
 }
 
 /*
@@ -181,7 +181,7 @@ static int check_port(__le16 port)
        if (port == 0)
                return -1;
 
-       sk_for_each(sk, node, &dn_sk_hash[dn_ntohs(port) & DN_SK_HASH_MASK]) {
+       sk_for_each(sk, node, &dn_sk_hash[le16_to_cpu(port) & DN_SK_HASH_MASK]) {
                struct dn_scp *scp = DN_SK(sk);
                if (scp->addrloc == port)
                        return -1;
@@ -195,12 +195,12 @@ static unsigned short port_alloc(struct sock *sk)
 static unsigned short port = 0x2000;
        unsigned short i_port = port;
 
-       while(check_port(dn_htons(++port)) != 0) {
+       while(check_port(cpu_to_le16(++port)) != 0) {
                if (port == i_port)
                        return 0;
        }
 
-       scp->addrloc = dn_htons(port);
+       scp->addrloc = cpu_to_le16(port);
 
        return 1;
 }
@@ -255,7 +255,7 @@ static struct hlist_head *listen_hash(struct sockaddr_dn *addr)
 
        if (hash == 0) {
                hash = addr->sdn_objnamel;
-               for(i = 0; i < dn_ntohs(addr->sdn_objnamel); i++) {
+               for(i = 0; i < le16_to_cpu(addr->sdn_objnamel); i++) {
                        hash ^= addr->sdn_objname[i];
                        hash ^= (hash << 3);
                }
@@ -297,16 +297,16 @@ int dn_sockaddr2username(struct sockaddr_dn *sdn, unsigned char *buf, unsigned c
                        break;
                case 1:
                        *buf++ = 0;
-                       *buf++ = dn_ntohs(sdn->sdn_objnamel);
-                       memcpy(buf, sdn->sdn_objname, dn_ntohs(sdn->sdn_objnamel));
-                       len = 3 + dn_ntohs(sdn->sdn_objnamel);
+                       *buf++ = le16_to_cpu(sdn->sdn_objnamel);
+                       memcpy(buf, sdn->sdn_objname, le16_to_cpu(sdn->sdn_objnamel));
+                       len = 3 + le16_to_cpu(sdn->sdn_objnamel);
                        break;
                case 2:
                        memset(buf, 0, 5);
                        buf += 5;
-                       *buf++ = dn_ntohs(sdn->sdn_objnamel);
-                       memcpy(buf, sdn->sdn_objname, dn_ntohs(sdn->sdn_objnamel));
-                       len = 7 + dn_ntohs(sdn->sdn_objnamel);
+                       *buf++ = le16_to_cpu(sdn->sdn_objnamel);
+                       memcpy(buf, sdn->sdn_objname, le16_to_cpu(sdn->sdn_objnamel));
+                       len = 7 + le16_to_cpu(sdn->sdn_objnamel);
                        break;
        }
 
@@ -327,7 +327,7 @@ int dn_username2sockaddr(unsigned char *data, int len, struct sockaddr_dn *sdn,
        int namel = 12;
 
        sdn->sdn_objnum = 0;
-       sdn->sdn_objnamel = dn_htons(0);
+       sdn->sdn_objnamel = cpu_to_le16(0);
        memset(sdn->sdn_objname, 0, DN_MAXOBJL);
 
        if (len < 2)
@@ -361,13 +361,13 @@ int dn_username2sockaddr(unsigned char *data, int len, struct sockaddr_dn *sdn,
        if (len < 0)
                return -1;
 
-       sdn->sdn_objnamel = dn_htons(*data++);
-       len -= dn_ntohs(sdn->sdn_objnamel);
+       sdn->sdn_objnamel = cpu_to_le16(*data++);
+       len -= le16_to_cpu(sdn->sdn_objnamel);
 
-       if ((len < 0) || (dn_ntohs(sdn->sdn_objnamel) > namel))
+       if ((len < 0) || (le16_to_cpu(sdn->sdn_objnamel) > namel))
                return -1;
 
-       memcpy(sdn->sdn_objname, data, dn_ntohs(sdn->sdn_objnamel));
+       memcpy(sdn->sdn_objname, data, le16_to_cpu(sdn->sdn_objnamel));
 
        return size - len;
 }
@@ -391,7 +391,7 @@ struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr)
                                continue;
                        if (scp->addr.sdn_objnamel != addr->sdn_objnamel)
                                continue;
-                       if (memcmp(scp->addr.sdn_objname, addr->sdn_objname, dn_ntohs(addr->sdn_objnamel)) != 0)
+                       if (memcmp(scp->addr.sdn_objname, addr->sdn_objname, le16_to_cpu(addr->sdn_objnamel)) != 0)
                                continue;
                }
                sock_hold(sk);
@@ -419,7 +419,7 @@ struct sock *dn_find_by_skb(struct sk_buff *skb)
        struct dn_scp *scp;
 
        read_lock(&dn_hash_lock);
-       sk_for_each(sk, node, &dn_sk_hash[dn_ntohs(cb->dst_port) & DN_SK_HASH_MASK]) {
+       sk_for_each(sk, node, &dn_sk_hash[le16_to_cpu(cb->dst_port) & DN_SK_HASH_MASK]) {
                scp = DN_SK(sk);
                if (cb->src != dn_saddr2dn(&scp->peer))
                        continue;
@@ -451,7 +451,7 @@ static void dn_destruct(struct sock *sk)
 
 static int dn_memory_pressure;
 
-static void dn_enter_memory_pressure(void)
+static void dn_enter_memory_pressure(struct sock *sk)
 {
        if (!dn_memory_pressure) {
                dn_memory_pressure = 1;
@@ -474,7 +474,7 @@ static struct proto dn_proto = {
 static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp)
 {
        struct dn_scp *scp;
-       struct sock *sk = sk_alloc(net, PF_DECnet, gfp, &dn_proto, 1);
+       struct sock *sk = sk_alloc(net, PF_DECnet, gfp, &dn_proto);
 
        if  (!sk)
                goto out;
@@ -675,11 +675,12 @@ char *dn_addr2asc(__u16 addr, char *buf)
 
 
 
-static int dn_create(struct net *net, struct socket *sock, int protocol)
+static int dn_create(struct net *net, struct socket *sock, int protocol,
+                    int kern)
 {
        struct sock *sk;
 
-       if (net != &init_net)
+       if (!net_eq(net, &init_net))
                return -EAFNOSUPPORT;
 
        switch(sock->type) {
@@ -734,10 +735,10 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (saddr->sdn_family != AF_DECnet)
                return -EINVAL;
 
-       if (dn_ntohs(saddr->sdn_nodeaddrl) && (dn_ntohs(saddr->sdn_nodeaddrl) != 2))
+       if (le16_to_cpu(saddr->sdn_nodeaddrl) && (le16_to_cpu(saddr->sdn_nodeaddrl) != 2))
                return -EINVAL;
 
-       if (dn_ntohs(saddr->sdn_objnamel) > DN_MAXOBJL)
+       if (le16_to_cpu(saddr->sdn_objnamel) > DN_MAXOBJL)
                return -EINVAL;
 
        if (saddr->sdn_flags & ~SDF_WILD)
@@ -748,10 +749,10 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                return -EACCES;
 
        if (!(saddr->sdn_flags & SDF_WILD)) {
-               if (dn_ntohs(saddr->sdn_nodeaddrl)) {
-                       read_lock(&dev_base_lock);
+               if (le16_to_cpu(saddr->sdn_nodeaddrl)) {
+                       rcu_read_lock();
                        ldev = NULL;
-                       for_each_netdev(dev) {
+                       for_each_netdev_rcu(&init_net, dev) {
                                if (!dev->dn_ptr)
                                        continue;
                                if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) {
@@ -759,7 +760,7 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                                        break;
                                }
                        }
-                       read_unlock(&dev_base_lock);
+                       rcu_read_unlock();
                        if (ldev == NULL)
                                return -EADDRNOTAVAIL;
                }
@@ -799,15 +800,15 @@ static int dn_auto_bind(struct socket *sock)
        if ((scp->accessdata.acc_accl != 0) &&
                (scp->accessdata.acc_accl <= 12)) {
 
-               scp->addr.sdn_objnamel = dn_htons(scp->accessdata.acc_accl);
-               memcpy(scp->addr.sdn_objname, scp->accessdata.acc_acc, dn_ntohs(scp->addr.sdn_objnamel));
+               scp->addr.sdn_objnamel = cpu_to_le16(scp->accessdata.acc_accl);
+               memcpy(scp->addr.sdn_objname, scp->accessdata.acc_acc, le16_to_cpu(scp->addr.sdn_objnamel));
 
                scp->accessdata.acc_accl = 0;
                memset(scp->accessdata.acc_acc, 0, 40);
        }
        /* End of compatibility stuff */
 
-       scp->addr.sdn_add.a_len = dn_htons(2);
+       scp->addr.sdn_add.a_len = cpu_to_le16(2);
        rv = dn_dev_bind_default((__le16 *)scp->addr.sdn_add.a_addr);
        if (rv == 0) {
                rv = dn_hash_sock(sk);
@@ -1027,7 +1028,7 @@ static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt)
        u16 len = *ptr++; /* yes, it's 8bit on the wire */
 
        BUG_ON(len > 16); /* we've checked the contents earlier */
-       opt->opt_optl   = dn_htons(len);
+       opt->opt_optl   = cpu_to_le16(len);
        opt->opt_status = 0;
        memcpy(opt->opt_data, ptr, len);
        skb_pull(skb, len + 1);
@@ -1075,6 +1076,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
        int err = 0;
        unsigned char type;
        long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
+       struct dst_entry *dst;
 
        lock_sock(sk);
 
@@ -1094,7 +1096,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
 
        cb = DN_SKB_CB(skb);
        sk->sk_ack_backlog--;
-       newsk = dn_alloc_sock(sk->sk_net, newsock, sk->sk_allocation);
+       newsk = dn_alloc_sock(sock_net(sk), newsock, sk->sk_allocation);
        if (newsk == NULL) {
                release_sock(sk);
                kfree_skb(skb);
@@ -1102,8 +1104,9 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
        }
        release_sock(sk);
 
-       dst_release(xchg(&newsk->sk_dst_cache, skb->dst));
-       skb->dst = NULL;
+       dst = skb_dst(skb);
+       dst_release(xchg(&newsk->sk_dst_cache, dst));
+       skb_dst_set(skb, NULL);
 
        DN_SK(newsk)->state        = DN_CR;
        DN_SK(newsk)->addrrem      = cb->src_port;
@@ -1238,7 +1241,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                return val;
 
        case TIOCOUTQ:
-               amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
+               amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
                if (amount < 0)
                        amount = 0;
                err = put_user(amount, (int __user *)arg);
@@ -1246,17 +1249,12 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
        case TIOCINQ:
                lock_sock(sk);
-               if ((skb = skb_peek(&scp->other_receive_queue)) != NULL) {
+               skb = skb_peek(&scp->other_receive_queue);
+               if (skb) {
                        amount = skb->len;
                } else {
-                       struct sk_buff *skb = sk->sk_receive_queue.next;
-                       for(;;) {
-                               if (skb ==
-                                   (struct sk_buff *)&sk->sk_receive_queue)
-                                       break;
+                       skb_queue_walk(&sk->sk_receive_queue, skb)
                                amount += skb->len;
-                               skb = skb->next;
-                       }
                }
                release_sock(sk);
                err = put_user(amount, (int __user *)arg);
@@ -1328,7 +1326,7 @@ out:
        return err;
 }
 
-static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        int err;
@@ -1340,7 +1338,7 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use
        return err;
 }
 
-static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, int optlen, int flags)
+static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, unsigned int optlen, int flags)
 {
        struct  sock *sk = sock->sk;
        struct dn_scp *scp = DN_SK(sk);
@@ -1375,7 +1373,7 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char __us
                        if (optlen != sizeof(struct optdata_dn))
                                return -EINVAL;
 
-                       if (dn_ntohs(u.opt.opt_optl) > 16)
+                       if (le16_to_cpu(u.opt.opt_optl) > 16)
                                return -EINVAL;
 
                        memcpy(&scp->conndata_out, &u.opt, optlen);
@@ -1388,7 +1386,7 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char __us
                        if (optlen != sizeof(struct optdata_dn))
                                return -EINVAL;
 
-                       if (dn_ntohs(u.opt.opt_optl) > 16)
+                       if (le16_to_cpu(u.opt.opt_optl) > 16)
                                return -EINVAL;
 
                        memcpy(&scp->discdata_out, &u.opt, optlen);
@@ -1579,16 +1577,16 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us
                default:
 #ifdef CONFIG_NETFILTER
                {
-                       int val, len;
+                       int ret, len;
 
                        if(get_user(len, optlen))
                                return -EFAULT;
 
-                       val = nf_getsockopt(sk, PF_DECnet, optname,
+                       ret = nf_getsockopt(sk, PF_DECnet, optname,
                                                        optval, &len);
-                       if (val >= 0)
-                               val = put_user(len, optlen);
-                       return val;
+                       if (ret >= 0)
+                               ret = put_user(len, optlen);
+                       return ret;
                }
 #endif
                case DSO_STREAM:
@@ -1643,13 +1641,13 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us
 
 static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, int target)
 {
-       struct sk_buff *skb = q->next;
+       struct sk_buff *skb;
        int len = 0;
 
        if (flags & MSG_OOB)
                return !skb_queue_empty(q) ? 1 : 0;
 
-       while(skb != (struct sk_buff *)q) {
+       skb_queue_walk(q, skb) {
                struct dn_skb_cb *cb = DN_SKB_CB(skb);
                len += skb->len;
 
@@ -1665,8 +1663,6 @@ static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, int
                /* minimum data length for read exceeded */
                if (len >= target)
                        return 1;
-
-               skb = skb->next;
        }
 
        return 0;
@@ -1682,7 +1678,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
        size_t target = size > 1 ? 1 : 0;
        size_t copied = 0;
        int rv = 0;
-       struct sk_buff *skb, *nskb;
+       struct sk_buff *skb, *n;
        struct dn_skb_cb *cb = NULL;
        unsigned char eor = 0;
        long timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
@@ -1719,6 +1715,8 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
         * See if there is data ready to read, sleep if there isn't
         */
        for(;;) {
+               DEFINE_WAIT(wait);
+
                if (sk->sk_err)
                        goto out;
 
@@ -1748,17 +1746,14 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
                        goto out;
                }
 
-               set_bit(SOCK_ASYNC_WAITDATA, &sock->flags);
-               SOCK_SLEEP_PRE(sk)
-
-               if (!dn_data_ready(sk, queue, flags, target))
-                       schedule();
-
-               SOCK_SLEEP_POST(sk)
-               clear_bit(SOCK_ASYNC_WAITDATA, &sock->flags);
+               prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+               set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+               sk_wait_event(sk, &timeo, dn_data_ready(sk, queue, flags, target));
+               clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+               finish_wait(sk->sk_sleep, &wait);
        }
 
-       for(skb = queue->next; skb != (struct sk_buff *)queue; skb = nskb) {
+       skb_queue_walk_safe(queue, skb, n) {
                unsigned int chunk = skb->len;
                cb = DN_SKB_CB(skb);
 
@@ -1775,7 +1770,6 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
                        skb_pull(skb, chunk);
 
                eor = cb->nsp_flags & 0x40;
-               nskb = skb->next;
 
                if (skb->len == 0) {
                        skb_unlink(skb, queue);
@@ -1904,7 +1898,7 @@ static inline struct sk_buff *dn_alloc_send_pskb(struct sock *sk,
        struct sk_buff *skb = sock_alloc_send_skb(sk, datalen,
                                                   noblock, errcode);
        if (skb) {
-               skb->protocol = __constant_htons(ETH_P_DNA_RT);
+               skb->protocol = htons(ETH_P_DNA_RT);
                skb->pkt_type = PACKET_OUTGOING;
        }
        return skb;
@@ -1962,7 +1956,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
        }
 
        if ((flags & MSG_TRYHARD) && sk->sk_dst_cache)
-               dst_negative_advice(&sk->sk_dst_cache);
+               dst_negative_advice(&sk->sk_dst_cache, sk);
 
        mss = scp->segsize_rem;
        fctype = scp->services_rem & NSP_FC_MASK;
@@ -2002,18 +1996,19 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
                 * size.
                 */
                if (dn_queue_too_long(scp, queue, flags)) {
+                       DEFINE_WAIT(wait);
+
                        if (flags & MSG_DONTWAIT) {
                                err = -EWOULDBLOCK;
                                goto out;
                        }
 
-                       SOCK_SLEEP_PRE(sk)
-
-                       if (dn_queue_too_long(scp, queue, flags))
-                               schedule();
-
-                       SOCK_SLEEP_POST(sk)
-
+                       prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+                       set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+                       sk_wait_event(sk, &timeo,
+                                     !dn_queue_too_long(scp, queue, flags));
+                       clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+                       finish_wait(sk->sk_sleep, &wait);
                        continue;
                }
 
@@ -2071,8 +2066,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
        }
 out:
 
-       if (skb)
-               kfree_skb(skb);
+       kfree_skb(skb);
 
        release_sock(sk);
 
@@ -2089,6 +2083,9 @@ static int dn_device_event(struct notifier_block *this, unsigned long event,
 {
        struct net_device *dev = (struct net_device *)ptr;
 
+       if (!net_eq(dev_net(dev), &init_net))
+               return NOTIFY_DONE;
+
        switch(event) {
                case NETDEV_UP:
                        dn_dev_up(dev);
@@ -2109,9 +2106,8 @@ static struct notifier_block dn_dev_notifier = {
 
 extern int dn_route_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
 
-static struct packet_type dn_dix_packet_type = {
-       .type =         __constant_htons(ETH_P_DNA_RT),
-       .dev =          NULL,           /* All devices */
+static struct packet_type dn_dix_packet_type __read_mostly = {
+       .type =         cpu_to_be16(ETH_P_DNA_RT),
        .func =         dn_route_rcv,
 };
 
@@ -2210,12 +2206,12 @@ static void dn_printable_object(struct sockaddr_dn *dn, unsigned char *buf)
 {
        int i;
 
-       switch (dn_ntohs(dn->sdn_objnamel)) {
+       switch (le16_to_cpu(dn->sdn_objnamel)) {
                case 0:
                        sprintf(buf, "%d", dn->sdn_objnum);
                        break;
                default:
-                       for (i = 0; i < dn_ntohs(dn->sdn_objnamel); i++) {
+                       for (i = 0; i < le16_to_cpu(dn->sdn_objnamel); i++) {
                                buf[i] = dn->sdn_objname[i];
                                if (IS_NOT_PRINTABLE(buf[i]))
                                        buf[i] = '.';
@@ -2278,7 +2274,7 @@ static inline void dn_socket_format_entry(struct seq_file *seq, struct sock *sk)
        seq_printf(seq,
                   "%6s/%04X %04d:%04d %04d:%04d %01d %-16s "
                   "%6s/%04X %04d:%04d %04d:%04d %01d %-16s %4s %s\n",
-                  dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->addr)), buf1),
+                  dn_addr2asc(le16_to_cpu(dn_saddr2dn(&scp->addr)), buf1),
                   scp->addrloc,
                   scp->numdat,
                   scp->numoth,
@@ -2286,7 +2282,7 @@ static inline void dn_socket_format_entry(struct seq_file *seq, struct sock *sk)
                   scp->ackxmt_oth,
                   scp->flowloc_sw,
                   local_object,
-                  dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->peer)), buf2),
+                  dn_addr2asc(le16_to_cpu(dn_saddr2dn(&scp->peer)), buf2),
                   scp->addrrem,
                   scp->numdat_rcv,
                   scp->numoth_rcv,
@@ -2317,25 +2313,8 @@ static const struct seq_operations dn_socket_seq_ops = {
 
 static int dn_socket_seq_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
-       int rc = -ENOMEM;
-       struct dn_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
-
-       if (!s)
-               goto out;
-
-       rc = seq_open(file, &dn_socket_seq_ops);
-       if (rc)
-               goto out_kfree;
-
-       seq             = file->private_data;
-       seq->private    = s;
-       memset(s, 0, sizeof(*s));
-out:
-       return rc;
-out_kfree:
-       kfree(s);
-       goto out;
+       return seq_open_private(file, &dn_socket_seq_ops,
+                       sizeof(struct dn_iter_state));
 }
 
 static const struct file_operations dn_socket_seq_fops = {
@@ -2347,7 +2326,7 @@ static const struct file_operations dn_socket_seq_fops = {
 };
 #endif
 
-static struct net_proto_family dn_family_ops = {
+static const struct net_proto_family   dn_family_ops = {
        .family =       AF_DECnet,
        .create =       dn_create,
        .owner  =       THIS_MODULE,
@@ -2435,6 +2414,8 @@ static void __exit decnet_exit(void)
        proc_net_remove(&init_net, "decnet");
 
        proto_unregister(&dn_proto);
+
+       rcu_barrier_bh(); /* Wait for completion of call_rcu_bh()'s */
 }
 module_exit(decnet_exit);
 #endif