[NETFILTER]: xt_conntrack: fix missing boolean clamping
[safe/jmp/linux-2.6] / net / irda / af_irda.c
index fbfa967..240b0cb 100644 (file)
@@ -42,7 +42,7 @@
  *
  ********************************************************************/
 
-#include <linux/config.h>
+#include <linux/capability.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/socket.h>
@@ -60,7 +60,7 @@
 
 #include <net/irda/af_irda.h>
 
-static int irda_create(struct socket *sock, int protocol);
+static int irda_create(struct net *net, struct socket *sock, int protocol);
 
 static const struct proto_ops irda_stream_ops;
 static const struct proto_ops irda_seqpacket_ops;
@@ -89,7 +89,6 @@ static int irda_data_indication(void *instance, void *sap, struct sk_buff *skb)
 
        self = instance;
        sk = instance;
-       IRDA_ASSERT(sk != NULL, return -1;);
 
        err = sock_queue_rcv_skb(sk, skb);
        if (err) {
@@ -131,14 +130,12 @@ static void irda_disconnect_indication(void *instance, void *sap,
        }
 
        /* Prevent race conditions with irda_release() and irda_shutdown() */
+       bh_lock_sock(sk);
        if (!sock_flag(sk, SOCK_DEAD) && sk->sk_state != TCP_CLOSE) {
                sk->sk_state     = TCP_CLOSE;
-               sk->sk_err       = ECONNRESET;
                sk->sk_shutdown |= SEND_SHUTDOWN;
 
                sk->sk_state_change(sk);
-               /* Uh-oh... Should use sock_orphan ? */
-                sock_set_flag(sk, SOCK_DEAD);
 
                /* Close our TSAP.
                 * If we leave it open, IrLMP put it back into the list of
@@ -157,7 +154,8 @@ static void irda_disconnect_indication(void *instance, void *sap,
                        irttp_close_tsap(self->tsap);
                        self->tsap = NULL;
                }
-        }
+       }
+       bh_unlock_sock(sk);
 
        /* Note : once we are there, there is not much you want to do
         * with the socket anymore, apart from closing it.
@@ -220,7 +218,7 @@ static void irda_connect_confirm(void *instance, void *sap,
                break;
        default:
                self->max_data_size = irttp_get_max_seg_size(self->tsap);
-       };
+       }
 
        IRDA_DEBUG(2, "%s(), max_data_size=%d\n", __FUNCTION__,
                   self->max_data_size);
@@ -283,7 +281,7 @@ static void irda_connect_indication(void *instance, void *sap,
                break;
        default:
                self->max_data_size = irttp_get_max_seg_size(self->tsap);
-       };
+       }
 
        IRDA_DEBUG(2, "%s(), max_data_size=%d\n", __FUNCTION__,
                   self->max_data_size);
@@ -306,9 +304,8 @@ static void irda_connect_response(struct irda_sock *self)
 
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
-       IRDA_ASSERT(self != NULL, return;);
-
-       skb = dev_alloc_skb(64);
+       skb = alloc_skb(TTP_MAX_HEADER + TTP_SAR_HEADER,
+                       GFP_ATOMIC);
        if (skb == NULL) {
                IRDA_DEBUG(0, "%s() Unable to allocate sk_buff!\n",
                           __FUNCTION__);
@@ -336,7 +333,7 @@ static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
 
        self = instance;
        sk = instance;
-       IRDA_ASSERT(sk != NULL, return;);
+       BUG_ON(sk == NULL);
 
        switch (flow) {
        case FLOW_STOP:
@@ -448,7 +445,7 @@ static void irda_discovery_timeout(u_long priv)
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
        self = (struct irda_sock *) priv;
-       IRDA_ASSERT(self != NULL, return;);
+       BUG_ON(self == NULL);
 
        /* Nothing for the caller */
        self->cachelog = NULL;
@@ -545,8 +542,6 @@ static int irda_find_lsap_sel(struct irda_sock *self, char *name)
 {
        IRDA_DEBUG(2, "%s(%p, %s)\n", __FUNCTION__, self, name);
 
-       IRDA_ASSERT(self != NULL, return -1;);
-
        if (self->iriap) {
                IRDA_WARNING("%s(): busy with a previous query\n",
                             __FUNCTION__);
@@ -634,8 +629,6 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
 
        IRDA_DEBUG(2, "%s(), name=%s\n", __FUNCTION__, name);
 
-       IRDA_ASSERT(self != NULL, return -1;);
-
        /* Ask lmp for the current discovery log
         * Note : we have to use irlmp_get_discoveries(), as opposed
         * to play with the cachelog directly, because while we are
@@ -783,8 +776,6 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        struct irda_sock *self = irda_sk(sk);
        int err;
 
-       IRDA_ASSERT(self != NULL, return -1;);
-
        IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
        if (addr_len != sizeof(struct sockaddr_irda))
@@ -811,12 +802,18 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        }
 #endif /* CONFIG_IRDA_ULTRA */
 
+       self->ias_obj = irias_new_object(addr->sir_name, jiffies);
+       if (self->ias_obj == NULL)
+               return -ENOMEM;
+
        err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name);
-       if (err < 0)
+       if (err < 0) {
+               kfree(self->ias_obj->name);
+               kfree(self->ias_obj);
                return err;
+       }
 
        /*  Register with LM-IAS */
-       self->ias_obj = irias_new_object(addr->sir_name, jiffies);
        irias_add_integer_attrib(self->ias_obj, "IrDA:TinyTP:LsapSel",
                                 self->stsap_sel, IAS_KERNEL_ATTR);
        irias_insert_object(self->ias_obj);
@@ -840,9 +837,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
 
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
-       IRDA_ASSERT(self != NULL, return -1;);
-
-       err = irda_create(newsock, sk->sk_protocol);
+       err = irda_create(sk->sk_net, newsock, sk->sk_protocol);
        if (err)
                return err;
 
@@ -872,44 +867,28 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
         * calling us, the data is waiting for us ;-)
         * Jean II
         */
-       skb = skb_dequeue(&sk->sk_receive_queue);
-       if (skb == NULL) {
-               int ret = 0;
-               DECLARE_WAITQUEUE(waitq, current);
+       while (1) {
+               skb = skb_dequeue(&sk->sk_receive_queue);
+               if (skb)
+                       break;
 
                /* Non blocking operation */
                if (flags & O_NONBLOCK)
                        return -EWOULDBLOCK;
 
-               /* The following code is a cut'n'paste of the
-                * wait_event_interruptible() macro.
-                * We don't us the macro because the condition has
-                * side effects : we want to make sure that only one
-                * skb get dequeued - Jean II */
-               add_wait_queue(sk->sk_sleep, &waitq);
-               for (;;) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       skb = skb_dequeue(&sk->sk_receive_queue);
-                       if (skb != NULL)
-                               break;
-                       if (!signal_pending(current)) {
-                               schedule();
-                               continue;
-                       }
-                       ret = -ERESTARTSYS;
-                       break;
-               }
-               current->state = TASK_RUNNING;
-               remove_wait_queue(sk->sk_sleep, &waitq);
-               if(ret)
-                       return -ERESTARTSYS;
+               err = wait_event_interruptible(*(sk->sk_sleep),
+                                       skb_peek(&sk->sk_receive_queue));
+               if (err)
+                       return err;
        }
 
        newsk = newsock->sk;
+       if (newsk == NULL)
+               return -EIO;
+
        newsk->sk_state = TCP_ESTABLISHED;
 
        new = irda_sk(newsk);
-       IRDA_ASSERT(new != NULL, return -1;);
 
        /* Now attach up the new socket */
        new->tsap = irttp_dup(self->tsap, new);
@@ -1060,7 +1039,8 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
 
        if (sk->sk_state != TCP_ESTABLISHED) {
                sock->state = SS_UNCONNECTED;
-               return sock_error(sk);  /* Always set at this point */
+               err = sock_error(sk);
+               return err? err : -ECONNRESET;
        }
 
        sock->state = SS_CONNECTED;
@@ -1083,13 +1063,16 @@ static struct proto irda_proto = {
  *    Create IrDA socket
  *
  */
-static int irda_create(struct socket *sock, int protocol)
+static int irda_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        struct irda_sock *self;
 
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        /* Check for valid socket type */
        switch (sock->type) {
        case SOCK_STREAM:     /* For TTP connections with SAR disabled */
@@ -1101,7 +1084,7 @@ static int irda_create(struct socket *sock, int protocol)
        }
 
        /* Allocate networking socket */
-       sk = sk_alloc(PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
+       sk = sk_alloc(net, PF_IRDA, GFP_ATOMIC, &irda_proto);
        if (sk == NULL)
                return -ENOMEM;
 
@@ -1141,8 +1124,6 @@ static int irda_create(struct socket *sock, int protocol)
                        self->max_sdu_size_rx = TTP_SAR_UNBOUND;
                        break;
                default:
-                       IRDA_ERROR("%s: protocol not supported!\n",
-                                  __FUNCTION__);
                        return -ESOCKTNOSUPPORT;
                }
                break;
@@ -1170,8 +1151,6 @@ static void irda_destroy_socket(struct irda_sock *self)
 {
        IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
-       IRDA_ASSERT(self != NULL, return;);
-
        /* Unregister with IrLMP */
        irlmp_unregister_client(self->ckey);
        irlmp_unregister_service(self->skey);
@@ -1209,9 +1188,10 @@ static int irda_release(struct socket *sock)
 
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
-        if (sk == NULL)
+       if (sk == NULL)
                return 0;
 
+       lock_sock(sk);
        sk->sk_state       = TCP_CLOSE;
        sk->sk_shutdown   |= SEND_SHUTDOWN;
        sk->sk_state_change(sk);
@@ -1221,6 +1201,7 @@ static int irda_release(struct socket *sock)
 
        sock_orphan(sk);
        sock->sk   = NULL;
+       release_sock(sk);
 
        /* Purge queues (see sock_init_data()) */
        skb_queue_purge(&sk->sk_receive_queue);
@@ -1255,7 +1236,7 @@ static int irda_release(struct socket *sock)
         * memory leak is now gone... - Jean II
         */
 
-        return 0;
+       return 0;
 }
 
 /*
@@ -1271,25 +1252,22 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
        struct sock *sk = sock->sk;
        struct irda_sock *self;
        struct sk_buff *skb;
-       unsigned char *asmptr;
-       int err;
+       int err = -EPIPE;
 
        IRDA_DEBUG(4, "%s(), len=%zd\n", __FUNCTION__, len);
 
        /* Note : socket.c set MSG_EOR on SEQPACKET sockets */
-       if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
+       if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT |
+                              MSG_NOSIGNAL))
                return -EINVAL;
 
-       if (sk->sk_shutdown & SEND_SHUTDOWN) {
-               send_sig(SIGPIPE, current, 0);
-               return -EPIPE;
-       }
+       if (sk->sk_shutdown & SEND_SHUTDOWN)
+               goto out_err;
 
        if (sk->sk_state != TCP_ESTABLISHED)
                return -ENOTCONN;
 
        self = irda_sk(sk);
-       IRDA_ASSERT(self != NULL, return -1;);
 
        /* Check if IrTTP is wants us to slow down */
 
@@ -1301,25 +1279,25 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
        if (sk->sk_state != TCP_ESTABLISHED)
                return -ENOTCONN;
 
-       /* Check that we don't send out to big frames */
+       /* Check that we don't send out too big frames */
        if (len > self->max_data_size) {
                IRDA_DEBUG(2, "%s(), Chopping frame from %zd to %d bytes!\n",
                           __FUNCTION__, len, self->max_data_size);
                len = self->max_data_size;
        }
 
-       skb = sock_alloc_send_skb(sk, len + self->max_header_size + 16, 
+       skb = sock_alloc_send_skb(sk, len + self->max_header_size + 16,
                                  msg->msg_flags & MSG_DONTWAIT, &err);
        if (!skb)
-               return -ENOBUFS;
+               goto out_err;
 
        skb_reserve(skb, self->max_header_size + 16);
-
-       asmptr = skb->h.raw = skb_put(skb, len);
-       err = memcpy_fromiovec(asmptr, msg->msg_iov, len);
+       skb_reset_transport_header(skb);
+       skb_put(skb, len);
+       err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
        if (err) {
                kfree_skb(skb);
-               return err;
+               goto out_err;
        }
 
        /*
@@ -1329,10 +1307,14 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
        err = irttp_data_request(self->tsap, skb);
        if (err) {
                IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
-               return err;
+               goto out_err;
        }
        /* Tell client how much data we actually sent */
        return len;
+
+ out_err:
+       return sk_stream_error(sk, msg->msg_flags, err);
+
 }
 
 /*
@@ -1352,15 +1334,16 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
 
        IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
-       IRDA_ASSERT(self != NULL, return -1;);
+       if ((err = sock_error(sk)) < 0)
+               return err;
 
        skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                flags & MSG_DONTWAIT, &err);
        if (!skb)
                return err;
 
-       skb->h.raw = skb->data;
-       copied     = skb->len;
+       skb_reset_transport_header(skb);
+       copied = skb->len;
 
        if (copied > size) {
                IRDA_DEBUG(2, "%s(), Received truncated frame (%zd < %zd)!\n",
@@ -1399,12 +1382,13 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
        struct irda_sock *self = irda_sk(sk);
        int noblock = flags & MSG_DONTWAIT;
        size_t copied = 0;
-       int target = 1;
-       DECLARE_WAITQUEUE(waitq, current);
+       int target, err;
+       long timeo;
 
        IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
-       IRDA_ASSERT(self != NULL, return -1;);
+       if ((err = sock_error(sk)) < 0)
+               return err;
 
        if (sock->flags & __SO_ACCEPTCON)
                return(-EINVAL);
@@ -1412,8 +1396,8 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
        if (flags & MSG_OOB)
                return -EOPNOTSUPP;
 
-       if (flags & MSG_WAITALL)
-               target = size;
+       target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
+       timeo = sock_rcvtimeo(sk, noblock);
 
        msg->msg_namelen = 0;
 
@@ -1421,42 +1405,37 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
                int chunk;
                struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
 
-               if (skb==NULL) {
+               if (skb == NULL) {
+                       DEFINE_WAIT(wait);
                        int ret = 0;
 
                        if (copied >= target)
                                break;
 
-                       /* The following code is a cut'n'paste of the
-                        * wait_event_interruptible() macro.
-                        * We don't us the macro because the test condition
-                        * is messy. - Jean II */
-                       set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
-                       add_wait_queue(sk->sk_sleep, &waitq);
-                       set_current_state(TASK_INTERRUPTIBLE);
+                       prepare_to_wait_exclusive(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 
                        /*
                         *      POSIX 1003.1g mandates this order.
                         */
                        ret = sock_error(sk);
                        if (ret)
-                               break;
+                               ;
                        else if (sk->sk_shutdown & RCV_SHUTDOWN)
                                ;
                        else if (noblock)
                                ret = -EAGAIN;
                        else if (signal_pending(current))
-                               ret = -ERESTARTSYS;
+                               ret = sock_intr_errno(timeo);
+                       else if (sk->sk_state != TCP_ESTABLISHED)
+                               ret = -ENOTCONN;
                        else if (skb_peek(&sk->sk_receive_queue) == NULL)
                                /* Wait process until data arrives */
                                schedule();
 
-                       current->state = TASK_RUNNING;
-                       remove_wait_queue(sk->sk_sleep, &waitq);
-                       clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+                       finish_wait(sk->sk_sleep, &wait);
 
-                       if(ret)
-                               return(ret);
+                       if (ret)
+                               return ret;
                        if (sk->sk_shutdown & RCV_SHUTDOWN)
                                break;
 
@@ -1525,7 +1504,6 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
        struct sock *sk = sock->sk;
        struct irda_sock *self;
        struct sk_buff *skb;
-       unsigned char *asmptr;
        int err;
 
        IRDA_DEBUG(4, "%s(), len=%zd\n", __FUNCTION__, len);
@@ -1542,10 +1520,9 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
                return -ENOTCONN;
 
        self = irda_sk(sk);
-       IRDA_ASSERT(self != NULL, return -1;);
 
        /*
-        * Check that we don't send out to big frames. This is an unreliable
+        * Check that we don't send out too big frames. This is an unreliable
         * service, so we have no fragmentation and no coalescence
         */
        if (len > self->max_data_size) {
@@ -1561,10 +1538,11 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
                return -ENOBUFS;
 
        skb_reserve(skb, self->max_header_size);
+       skb_reset_transport_header(skb);
 
        IRDA_DEBUG(4, "%s(), appending user data\n", __FUNCTION__);
-       asmptr = skb->h.raw = skb_put(skb, len);
-       err = memcpy_fromiovec(asmptr, msg->msg_iov, len);
+       skb_put(skb, len);
+       err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
        if (err) {
                kfree_skb(skb);
                return err;
@@ -1597,7 +1575,6 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
        __u8 pid = 0;
        int bound = 0;
        struct sk_buff *skb;
-       unsigned char *asmptr;
        int err;
 
        IRDA_DEBUG(4, "%s(), len=%zd\n", __FUNCTION__, len);
@@ -1611,7 +1588,6 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
        }
 
        self = irda_sk(sk);
-       IRDA_ASSERT(self != NULL, return -1;);
 
        /* Check if an address was specified with sendto. Jean II */
        if (msg->msg_name) {
@@ -1641,7 +1617,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
        }
 
        /*
-        * Check that we don't send out to big frames. This is an unreliable
+        * Check that we don't send out too big frames. This is an unreliable
         * service, so we have no fragmentation and no coalescence
         */
        if (len > self->max_data_size) {
@@ -1657,10 +1633,11 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
                return -ENOBUFS;
 
        skb_reserve(skb, self->max_header_size);
+       skb_reset_transport_header(skb);
 
        IRDA_DEBUG(4, "%s(), appending user data\n", __FUNCTION__);
-       asmptr = skb->h.raw = skb_put(skb, len);
-       err = memcpy_fromiovec(asmptr, msg->msg_iov, len);
+       skb_put(skb, len);
+       err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
        if (err) {
                kfree_skb(skb);
                return err;
@@ -1684,8 +1661,6 @@ static int irda_shutdown(struct socket *sock, int how)
        struct sock *sk = sock->sk;
        struct irda_sock *self = irda_sk(sk);
 
-       IRDA_ASSERT(self != NULL, return -1;);
-
        IRDA_DEBUG(1, "%s(%p)\n", __FUNCTION__, self);
 
        sk->sk_state       = TCP_CLOSE;
@@ -1708,7 +1683,7 @@ static int irda_shutdown(struct socket *sock, int how)
        self->daddr = DEV_ADDR_ANY;     /* Until we get re-connected */
        self->saddr = 0x0;              /* so IrLMP assign us any link */
 
-        return 0;
+       return 0;
 }
 
 /*
@@ -1829,6 +1804,19 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        return 0;
 }
 
+#ifdef CONFIG_COMPAT
+/*
+ * Function irda_ioctl (sock, cmd, arg)
+ */
+static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+       /*
+        * All IRDA's ioctl are standard ones.
+        */
+       return -ENOIOCTLCMD;
+}
+#endif
+
 /*
  * Function irda_setsockopt (sock, level, optname, optval, optlen)
  *
@@ -1843,9 +1831,7 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
        struct irda_ias_set    *ias_opt;
        struct ias_object      *ias_obj;
        struct ias_attrib *     ias_attr;       /* Attribute in IAS object */
-       int opt;
-
-       IRDA_ASSERT(self != NULL, return -1;);
+       int opt, free_ias = 0;
 
        IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
@@ -1901,11 +1887,20 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
                        /* Create a new object */
                        ias_obj = irias_new_object(ias_opt->irda_class_name,
                                                   jiffies);
+                       if (ias_obj == NULL) {
+                               kfree(ias_opt);
+                               return -ENOMEM;
+                       }
+                       free_ias = 1;
                }
 
                /* Do we have the attribute already ? */
                if(irias_find_attrib(ias_obj, ias_opt->irda_attrib_name)) {
                        kfree(ias_opt);
+                       if (free_ias) {
+                               kfree(ias_obj->name);
+                               kfree(ias_obj);
+                       }
                        return -EINVAL;
                }
 
@@ -1924,6 +1919,11 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
                        if(ias_opt->attribute.irda_attrib_octet_seq.len >
                           IAS_MAX_OCTET_STRING) {
                                kfree(ias_opt);
+                               if (free_ias) {
+                                       kfree(ias_obj->name);
+                                       kfree(ias_obj);
+                               }
+
                                return -EINVAL;
                        }
                        /* Add an octet sequence attribute */
@@ -1952,6 +1952,10 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
                        break;
                default :
                        kfree(ias_opt);
+                       if (free_ias) {
+                               kfree(ias_obj->name);
+                               kfree(ias_obj);
+                       }
                        return -EINVAL;
                }
                irias_insert_object(ias_obj);
@@ -2406,9 +2410,8 @@ bed:
 
                        /* Set watchdog timer to expire in <val> ms. */
                        self->errno = 0;
-                       init_timer(&self->watchdog);
-                       self->watchdog.function = irda_discovery_timeout;
-                       self->watchdog.data = (unsigned long) self;
+                       setup_timer(&self->watchdog, irda_discovery_timeout,
+                                       (unsigned long)self);
                        self->watchdog.expires = jiffies + (val * HZ/1000);
                        add_timer(&(self->watchdog));
 
@@ -2475,6 +2478,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
        .getname =      irda_getname,
        .poll =         irda_poll,
        .ioctl =        irda_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = irda_compat_ioctl,
+#endif
        .listen =       irda_listen,
        .shutdown =     irda_shutdown,
        .setsockopt =   irda_setsockopt,
@@ -2496,6 +2502,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
        .getname =      irda_getname,
        .poll =         datagram_poll,
        .ioctl =        irda_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = irda_compat_ioctl,
+#endif
        .listen =       irda_listen,
        .shutdown =     irda_shutdown,
        .setsockopt =   irda_setsockopt,
@@ -2517,6 +2526,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
        .getname =      irda_getname,
        .poll =         datagram_poll,
        .ioctl =        irda_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = irda_compat_ioctl,
+#endif
        .listen =       irda_listen,
        .shutdown =     irda_shutdown,
        .setsockopt =   irda_setsockopt,
@@ -2539,6 +2551,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
        .getname =      irda_getname,
        .poll =         datagram_poll,
        .ioctl =        irda_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = irda_compat_ioctl,
+#endif
        .listen =       sock_no_listen,
        .shutdown =     irda_shutdown,
        .setsockopt =   irda_setsockopt,
@@ -2550,7 +2565,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
 };
 #endif /* CONFIG_IRDA_ULTRA */
 
-#include <linux/smp_lock.h>
 SOCKOPS_WRAP(irda_stream, PF_IRDA);
 SOCKOPS_WRAP(irda_seqpacket, PF_IRDA);
 SOCKOPS_WRAP(irda_dgram, PF_IRDA);
@@ -2580,7 +2594,7 @@ int __init irsock_init(void)
  *    Remove IrDA protocol
  *
  */
-void __exit irsock_cleanup(void)
+void irsock_cleanup(void)
 {
        sock_unregister(PF_IRDA);
        proto_unregister(&irda_proto);