mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-09 14:50:19 +00:00
net/irda: push BKL into proto_ops
The irda driver uses the BKL implicitly in its protocol operations. Replace the wrapped proto_ops with explicit lock_kernel() calls makes the usage more obvious and shrinks the size of the object code. The calls t lock_kernel() should eventually all be replaced by other serialization methods, which requires finding out The calls t lock_kernel() should eventually all be replaced by other serialization methods, which requires finding out which data actually needs protection. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
83927ba069
commit
58a9d73202
@ -714,11 +714,14 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
|
|||||||
struct sockaddr_irda saddr;
|
struct sockaddr_irda saddr;
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
struct irda_sock *self = irda_sk(sk);
|
struct irda_sock *self = irda_sk(sk);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
memset(&saddr, 0, sizeof(saddr));
|
memset(&saddr, 0, sizeof(saddr));
|
||||||
if (peer) {
|
if (peer) {
|
||||||
|
err = -ENOTCONN;
|
||||||
if (sk->sk_state != TCP_ESTABLISHED)
|
if (sk->sk_state != TCP_ESTABLISHED)
|
||||||
return -ENOTCONN;
|
goto out;
|
||||||
|
|
||||||
saddr.sir_family = AF_IRDA;
|
saddr.sir_family = AF_IRDA;
|
||||||
saddr.sir_lsap_sel = self->dtsap_sel;
|
saddr.sir_lsap_sel = self->dtsap_sel;
|
||||||
@ -735,8 +738,10 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
|
|||||||
/* uaddr_len come to us uninitialised */
|
/* uaddr_len come to us uninitialised */
|
||||||
*uaddr_len = sizeof (struct sockaddr_irda);
|
*uaddr_len = sizeof (struct sockaddr_irda);
|
||||||
memcpy(uaddr, &saddr, *uaddr_len);
|
memcpy(uaddr, &saddr, *uaddr_len);
|
||||||
|
err = 0;
|
||||||
return 0;
|
out:
|
||||||
|
unlock_kernel();
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -748,21 +753,25 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
|
|||||||
static int irda_listen(struct socket *sock, int backlog)
|
static int irda_listen(struct socket *sock, int backlog)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
|
int err = -EOPNOTSUPP;
|
||||||
|
|
||||||
IRDA_DEBUG(2, "%s()\n", __func__);
|
IRDA_DEBUG(2, "%s()\n", __func__);
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) &&
|
if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) &&
|
||||||
(sk->sk_type != SOCK_DGRAM))
|
(sk->sk_type != SOCK_DGRAM))
|
||||||
return -EOPNOTSUPP;
|
goto out;
|
||||||
|
|
||||||
if (sk->sk_state != TCP_LISTEN) {
|
if (sk->sk_state != TCP_LISTEN) {
|
||||||
sk->sk_max_ack_backlog = backlog;
|
sk->sk_max_ack_backlog = backlog;
|
||||||
sk->sk_state = TCP_LISTEN;
|
sk->sk_state = TCP_LISTEN;
|
||||||
|
|
||||||
return 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
return -EOPNOTSUPP;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -783,36 +792,40 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||||||
if (addr_len != sizeof(struct sockaddr_irda))
|
if (addr_len != sizeof(struct sockaddr_irda))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
#ifdef CONFIG_IRDA_ULTRA
|
#ifdef CONFIG_IRDA_ULTRA
|
||||||
/* Special care for Ultra sockets */
|
/* Special care for Ultra sockets */
|
||||||
if ((sk->sk_type == SOCK_DGRAM) &&
|
if ((sk->sk_type == SOCK_DGRAM) &&
|
||||||
(sk->sk_protocol == IRDAPROTO_ULTRA)) {
|
(sk->sk_protocol == IRDAPROTO_ULTRA)) {
|
||||||
self->pid = addr->sir_lsap_sel;
|
self->pid = addr->sir_lsap_sel;
|
||||||
|
err = -EOPNOTSUPP;
|
||||||
if (self->pid & 0x80) {
|
if (self->pid & 0x80) {
|
||||||
IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__);
|
IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__);
|
||||||
return -EOPNOTSUPP;
|
goto out;
|
||||||
}
|
}
|
||||||
err = irda_open_lsap(self, self->pid);
|
err = irda_open_lsap(self, self->pid);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
/* Pretend we are connected */
|
/* Pretend we are connected */
|
||||||
sock->state = SS_CONNECTED;
|
sock->state = SS_CONNECTED;
|
||||||
sk->sk_state = TCP_ESTABLISHED;
|
sk->sk_state = TCP_ESTABLISHED;
|
||||||
|
err = 0;
|
||||||
|
|
||||||
return 0;
|
goto out;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IRDA_ULTRA */
|
#endif /* CONFIG_IRDA_ULTRA */
|
||||||
|
|
||||||
self->ias_obj = irias_new_object(addr->sir_name, jiffies);
|
self->ias_obj = irias_new_object(addr->sir_name, jiffies);
|
||||||
|
err = -ENOMEM;
|
||||||
if (self->ias_obj == NULL)
|
if (self->ias_obj == NULL)
|
||||||
return -ENOMEM;
|
goto out;
|
||||||
|
|
||||||
err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name);
|
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->name);
|
||||||
kfree(self->ias_obj);
|
kfree(self->ias_obj);
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register with LM-IAS */
|
/* Register with LM-IAS */
|
||||||
@ -820,7 +833,10 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||||||
self->stsap_sel, IAS_KERNEL_ATTR);
|
self->stsap_sel, IAS_KERNEL_ATTR);
|
||||||
irias_insert_object(self->ias_obj);
|
irias_insert_object(self->ias_obj);
|
||||||
|
|
||||||
return 0;
|
err = 0;
|
||||||
|
out:
|
||||||
|
unlock_kernel();
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -839,22 +855,26 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
|
|||||||
|
|
||||||
IRDA_DEBUG(2, "%s()\n", __func__);
|
IRDA_DEBUG(2, "%s()\n", __func__);
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0);
|
err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
|
err = -EINVAL;
|
||||||
if (sock->state != SS_UNCONNECTED)
|
if (sock->state != SS_UNCONNECTED)
|
||||||
return -EINVAL;
|
goto out;
|
||||||
|
|
||||||
if ((sk = sock->sk) == NULL)
|
if ((sk = sock->sk) == NULL)
|
||||||
return -EINVAL;
|
goto out;
|
||||||
|
|
||||||
|
err = -EOPNOTSUPP;
|
||||||
if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) &&
|
if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) &&
|
||||||
(sk->sk_type != SOCK_DGRAM))
|
(sk->sk_type != SOCK_DGRAM))
|
||||||
return -EOPNOTSUPP;
|
goto out;
|
||||||
|
|
||||||
|
err = -EINVAL;
|
||||||
if (sk->sk_state != TCP_LISTEN)
|
if (sk->sk_state != TCP_LISTEN)
|
||||||
return -EINVAL;
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The read queue this time is holding sockets ready to use
|
* The read queue this time is holding sockets ready to use
|
||||||
@ -875,18 +895,20 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Non blocking operation */
|
/* Non blocking operation */
|
||||||
|
err = -EWOULDBLOCK;
|
||||||
if (flags & O_NONBLOCK)
|
if (flags & O_NONBLOCK)
|
||||||
return -EWOULDBLOCK;
|
goto out;
|
||||||
|
|
||||||
err = wait_event_interruptible(*(sk->sk_sleep),
|
err = wait_event_interruptible(*(sk->sk_sleep),
|
||||||
skb_peek(&sk->sk_receive_queue));
|
skb_peek(&sk->sk_receive_queue));
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
newsk = newsock->sk;
|
newsk = newsock->sk;
|
||||||
|
err = -EIO;
|
||||||
if (newsk == NULL)
|
if (newsk == NULL)
|
||||||
return -EIO;
|
goto out;
|
||||||
|
|
||||||
newsk->sk_state = TCP_ESTABLISHED;
|
newsk->sk_state = TCP_ESTABLISHED;
|
||||||
|
|
||||||
@ -894,10 +916,11 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
|
|||||||
|
|
||||||
/* Now attach up the new socket */
|
/* Now attach up the new socket */
|
||||||
new->tsap = irttp_dup(self->tsap, new);
|
new->tsap = irttp_dup(self->tsap, new);
|
||||||
|
err = -EPERM; /* value does not seem to make sense. -arnd */
|
||||||
if (!new->tsap) {
|
if (!new->tsap) {
|
||||||
IRDA_DEBUG(0, "%s(), dup failed!\n", __func__);
|
IRDA_DEBUG(0, "%s(), dup failed!\n", __func__);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return -1;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
new->stsap_sel = new->tsap->stsap_sel;
|
new->stsap_sel = new->tsap->stsap_sel;
|
||||||
@ -921,8 +944,10 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
|
|||||||
newsock->state = SS_CONNECTED;
|
newsock->state = SS_CONNECTED;
|
||||||
|
|
||||||
irda_connect_response(new);
|
irda_connect_response(new);
|
||||||
|
err = 0;
|
||||||
return 0;
|
out:
|
||||||
|
unlock_kernel();
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -955,28 +980,34 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
|
|||||||
|
|
||||||
IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
|
IRDA_DEBUG(2, "%s(%p)\n", __func__, self);
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
/* Don't allow connect for Ultra sockets */
|
/* Don't allow connect for Ultra sockets */
|
||||||
|
err = -ESOCKTNOSUPPORT;
|
||||||
if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA))
|
if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA))
|
||||||
return -ESOCKTNOSUPPORT;
|
goto out;
|
||||||
|
|
||||||
if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
|
if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
|
||||||
sock->state = SS_CONNECTED;
|
sock->state = SS_CONNECTED;
|
||||||
return 0; /* Connect completed during a ERESTARTSYS event */
|
err = 0;
|
||||||
|
goto out; /* Connect completed during a ERESTARTSYS event */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
|
if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
|
||||||
sock->state = SS_UNCONNECTED;
|
sock->state = SS_UNCONNECTED;
|
||||||
return -ECONNREFUSED;
|
err = -ECONNREFUSED;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = -EISCONN; /* No reconnect on a seqpacket socket */
|
||||||
if (sk->sk_state == TCP_ESTABLISHED)
|
if (sk->sk_state == TCP_ESTABLISHED)
|
||||||
return -EISCONN; /* No reconnect on a seqpacket socket */
|
goto out;
|
||||||
|
|
||||||
sk->sk_state = TCP_CLOSE;
|
sk->sk_state = TCP_CLOSE;
|
||||||
sock->state = SS_UNCONNECTED;
|
sock->state = SS_UNCONNECTED;
|
||||||
|
|
||||||
|
err = -EINVAL;
|
||||||
if (addr_len != sizeof(struct sockaddr_irda))
|
if (addr_len != sizeof(struct sockaddr_irda))
|
||||||
return -EINVAL;
|
goto out;
|
||||||
|
|
||||||
/* Check if user supplied any destination device address */
|
/* Check if user supplied any destination device address */
|
||||||
if ((!addr->sir_addr) || (addr->sir_addr == DEV_ADDR_ANY)) {
|
if ((!addr->sir_addr) || (addr->sir_addr == DEV_ADDR_ANY)) {
|
||||||
@ -984,7 +1015,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
|
|||||||
err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name);
|
err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name);
|
||||||
if (err) {
|
if (err) {
|
||||||
IRDA_DEBUG(0, "%s(), auto-connect failed!\n", __func__);
|
IRDA_DEBUG(0, "%s(), auto-connect failed!\n", __func__);
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Use the one provided by the user */
|
/* Use the one provided by the user */
|
||||||
@ -1000,7 +1031,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
|
|||||||
err = irda_find_lsap_sel(self, addr->sir_name);
|
err = irda_find_lsap_sel(self, addr->sir_name);
|
||||||
if (err) {
|
if (err) {
|
||||||
IRDA_DEBUG(0, "%s(), connect failed!\n", __func__);
|
IRDA_DEBUG(0, "%s(), connect failed!\n", __func__);
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Directly connect to the remote LSAP
|
/* Directly connect to the remote LSAP
|
||||||
@ -1025,29 +1056,35 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
|
|||||||
self->max_sdu_size_rx, NULL);
|
self->max_sdu_size_rx, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
IRDA_DEBUG(0, "%s(), connect failed!\n", __func__);
|
IRDA_DEBUG(0, "%s(), connect failed!\n", __func__);
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now the loop */
|
/* Now the loop */
|
||||||
|
err = -EINPROGRESS;
|
||||||
if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
|
if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
|
||||||
return -EINPROGRESS;
|
goto out;
|
||||||
|
|
||||||
|
err = -ERESTARTSYS;
|
||||||
if (wait_event_interruptible(*(sk->sk_sleep),
|
if (wait_event_interruptible(*(sk->sk_sleep),
|
||||||
(sk->sk_state != TCP_SYN_SENT)))
|
(sk->sk_state != TCP_SYN_SENT)))
|
||||||
return -ERESTARTSYS;
|
goto out;
|
||||||
|
|
||||||
if (sk->sk_state != TCP_ESTABLISHED) {
|
if (sk->sk_state != TCP_ESTABLISHED) {
|
||||||
sock->state = SS_UNCONNECTED;
|
sock->state = SS_UNCONNECTED;
|
||||||
err = sock_error(sk);
|
err = sock_error(sk);
|
||||||
return err? err : -ECONNRESET;
|
if (!err)
|
||||||
|
err = -ECONNRESET;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sock->state = SS_CONNECTED;
|
sock->state = SS_CONNECTED;
|
||||||
|
|
||||||
/* At this point, IrLMP has assigned our source address */
|
/* At this point, IrLMP has assigned our source address */
|
||||||
self->saddr = irttp_get_saddr(self->tsap);
|
self->saddr = irttp_get_saddr(self->tsap);
|
||||||
|
err = 0;
|
||||||
return 0;
|
out:
|
||||||
|
unlock_kernel();
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct proto irda_proto = {
|
static struct proto irda_proto = {
|
||||||
@ -1193,6 +1230,7 @@ static int irda_release(struct socket *sock)
|
|||||||
if (sk == NULL)
|
if (sk == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
sk->sk_state = TCP_CLOSE;
|
sk->sk_state = TCP_CLOSE;
|
||||||
sk->sk_shutdown |= SEND_SHUTDOWN;
|
sk->sk_shutdown |= SEND_SHUTDOWN;
|
||||||
@ -1211,6 +1249,7 @@ static int irda_release(struct socket *sock)
|
|||||||
/* Destroy networking socket if we are the last reference on it,
|
/* Destroy networking socket if we are the last reference on it,
|
||||||
* i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */
|
* i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
/* Notes on socket locking and deallocation... - Jean II
|
/* Notes on socket locking and deallocation... - Jean II
|
||||||
* In theory we should put pairs of sock_hold() / sock_put() to
|
* In theory we should put pairs of sock_hold() / sock_put() to
|
||||||
@ -1258,28 +1297,37 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|||||||
|
|
||||||
IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
|
IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
/* Note : socket.c set MSG_EOR on SEQPACKET sockets */
|
/* 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))
|
MSG_NOSIGNAL)) {
|
||||||
return -EINVAL;
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (sk->sk_shutdown & SEND_SHUTDOWN)
|
if (sk->sk_shutdown & SEND_SHUTDOWN)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
if (sk->sk_state != TCP_ESTABLISHED)
|
if (sk->sk_state != TCP_ESTABLISHED) {
|
||||||
return -ENOTCONN;
|
err = -ENOTCONN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
self = irda_sk(sk);
|
self = irda_sk(sk);
|
||||||
|
|
||||||
/* Check if IrTTP is wants us to slow down */
|
/* Check if IrTTP is wants us to slow down */
|
||||||
|
|
||||||
if (wait_event_interruptible(*(sk->sk_sleep),
|
if (wait_event_interruptible(*(sk->sk_sleep),
|
||||||
(self->tx_flow != FLOW_STOP || sk->sk_state != TCP_ESTABLISHED)))
|
(self->tx_flow != FLOW_STOP || sk->sk_state != TCP_ESTABLISHED))) {
|
||||||
return -ERESTARTSYS;
|
err = -ERESTARTSYS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if we are still connected */
|
/* Check if we are still connected */
|
||||||
if (sk->sk_state != TCP_ESTABLISHED)
|
if (sk->sk_state != TCP_ESTABLISHED) {
|
||||||
return -ENOTCONN;
|
err = -ENOTCONN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check that we don't send out too big frames */
|
/* Check that we don't send out too big frames */
|
||||||
if (len > self->max_data_size) {
|
if (len > self->max_data_size) {
|
||||||
@ -1311,11 +1359,16 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|||||||
IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
|
IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock_kernel();
|
||||||
/* Tell client how much data we actually sent */
|
/* Tell client how much data we actually sent */
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
out_err:
|
out_err:
|
||||||
return sk_stream_error(sk, msg->msg_flags, err);
|
err = sk_stream_error(sk, msg->msg_flags, err);
|
||||||
|
out:
|
||||||
|
unlock_kernel();
|
||||||
|
return err;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1336,13 +1389,14 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
|
|||||||
|
|
||||||
IRDA_DEBUG(4, "%s()\n", __func__);
|
IRDA_DEBUG(4, "%s()\n", __func__);
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
if ((err = sock_error(sk)) < 0)
|
if ((err = sock_error(sk)) < 0)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
|
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
|
||||||
flags & MSG_DONTWAIT, &err);
|
flags & MSG_DONTWAIT, &err);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
skb_reset_transport_header(skb);
|
skb_reset_transport_header(skb);
|
||||||
copied = skb->len;
|
copied = skb->len;
|
||||||
@ -1370,8 +1424,12 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
|
|||||||
irttp_flow_request(self->tsap, FLOW_START);
|
irttp_flow_request(self->tsap, FLOW_START);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unlock_kernel();
|
||||||
return copied;
|
return copied;
|
||||||
|
|
||||||
|
out:
|
||||||
|
unlock_kernel();
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1389,15 +1447,19 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
|
|||||||
|
|
||||||
IRDA_DEBUG(3, "%s()\n", __func__);
|
IRDA_DEBUG(3, "%s()\n", __func__);
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
if ((err = sock_error(sk)) < 0)
|
if ((err = sock_error(sk)) < 0)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
|
err = -EINVAL;
|
||||||
if (sock->flags & __SO_ACCEPTCON)
|
if (sock->flags & __SO_ACCEPTCON)
|
||||||
return(-EINVAL);
|
goto out;
|
||||||
|
|
||||||
|
err =-EOPNOTSUPP;
|
||||||
if (flags & MSG_OOB)
|
if (flags & MSG_OOB)
|
||||||
return -EOPNOTSUPP;
|
goto out;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
|
target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
|
||||||
timeo = sock_rcvtimeo(sk, noblock);
|
timeo = sock_rcvtimeo(sk, noblock);
|
||||||
|
|
||||||
@ -1409,7 +1471,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
|
|||||||
|
|
||||||
if (skb == NULL) {
|
if (skb == NULL) {
|
||||||
DEFINE_WAIT(wait);
|
DEFINE_WAIT(wait);
|
||||||
int ret = 0;
|
err = 0;
|
||||||
|
|
||||||
if (copied >= target)
|
if (copied >= target)
|
||||||
break;
|
break;
|
||||||
@ -1419,25 +1481,25 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
|
|||||||
/*
|
/*
|
||||||
* POSIX 1003.1g mandates this order.
|
* POSIX 1003.1g mandates this order.
|
||||||
*/
|
*/
|
||||||
ret = sock_error(sk);
|
err = sock_error(sk);
|
||||||
if (ret)
|
if (err)
|
||||||
;
|
;
|
||||||
else if (sk->sk_shutdown & RCV_SHUTDOWN)
|
else if (sk->sk_shutdown & RCV_SHUTDOWN)
|
||||||
;
|
;
|
||||||
else if (noblock)
|
else if (noblock)
|
||||||
ret = -EAGAIN;
|
err = -EAGAIN;
|
||||||
else if (signal_pending(current))
|
else if (signal_pending(current))
|
||||||
ret = sock_intr_errno(timeo);
|
err = sock_intr_errno(timeo);
|
||||||
else if (sk->sk_state != TCP_ESTABLISHED)
|
else if (sk->sk_state != TCP_ESTABLISHED)
|
||||||
ret = -ENOTCONN;
|
err = -ENOTCONN;
|
||||||
else if (skb_peek(&sk->sk_receive_queue) == NULL)
|
else if (skb_peek(&sk->sk_receive_queue) == NULL)
|
||||||
/* Wait process until data arrives */
|
/* Wait process until data arrives */
|
||||||
schedule();
|
schedule();
|
||||||
|
|
||||||
finish_wait(sk->sk_sleep, &wait);
|
finish_wait(sk->sk_sleep, &wait);
|
||||||
|
|
||||||
if (ret)
|
if (err)
|
||||||
return ret;
|
goto out;
|
||||||
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1490,7 +1552,9 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return copied;
|
out:
|
||||||
|
unlock_kernel();
|
||||||
|
return err ? : copied;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1508,18 +1572,23 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
|
|||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
|
||||||
IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
|
IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
|
||||||
|
|
||||||
|
err = -EINVAL;
|
||||||
if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
|
if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
|
||||||
return -EINVAL;
|
goto out;
|
||||||
|
|
||||||
if (sk->sk_shutdown & SEND_SHUTDOWN) {
|
if (sk->sk_shutdown & SEND_SHUTDOWN) {
|
||||||
send_sig(SIGPIPE, current, 0);
|
send_sig(SIGPIPE, current, 0);
|
||||||
return -EPIPE;
|
err = -EPIPE;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = -ENOTCONN;
|
||||||
if (sk->sk_state != TCP_ESTABLISHED)
|
if (sk->sk_state != TCP_ESTABLISHED)
|
||||||
return -ENOTCONN;
|
goto out;
|
||||||
|
|
||||||
self = irda_sk(sk);
|
self = irda_sk(sk);
|
||||||
|
|
||||||
@ -1536,8 +1605,9 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
|
|||||||
|
|
||||||
skb = sock_alloc_send_skb(sk, len + self->max_header_size,
|
skb = sock_alloc_send_skb(sk, len + self->max_header_size,
|
||||||
msg->msg_flags & MSG_DONTWAIT, &err);
|
msg->msg_flags & MSG_DONTWAIT, &err);
|
||||||
|
err = -ENOBUFS;
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return -ENOBUFS;
|
goto out;
|
||||||
|
|
||||||
skb_reserve(skb, self->max_header_size);
|
skb_reserve(skb, self->max_header_size);
|
||||||
skb_reset_transport_header(skb);
|
skb_reset_transport_header(skb);
|
||||||
@ -1547,7 +1617,7 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
|
|||||||
err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
|
err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
|
||||||
if (err) {
|
if (err) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1557,9 +1627,13 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
|
|||||||
err = irttp_udata_request(self->tsap, skb);
|
err = irttp_udata_request(self->tsap, skb);
|
||||||
if (err) {
|
if (err) {
|
||||||
IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
|
IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
|
unlock_kernel();
|
||||||
return len;
|
return len;
|
||||||
|
out:
|
||||||
|
unlock_kernel();
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1581,12 +1655,15 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
|
|||||||
|
|
||||||
IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
|
IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len);
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
err = -EINVAL;
|
||||||
if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
|
if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
|
||||||
return -EINVAL;
|
goto out;
|
||||||
|
|
||||||
|
err = -EPIPE;
|
||||||
if (sk->sk_shutdown & SEND_SHUTDOWN) {
|
if (sk->sk_shutdown & SEND_SHUTDOWN) {
|
||||||
send_sig(SIGPIPE, current, 0);
|
send_sig(SIGPIPE, current, 0);
|
||||||
return -EPIPE;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
self = irda_sk(sk);
|
self = irda_sk(sk);
|
||||||
@ -1594,16 +1671,18 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
|
|||||||
/* Check if an address was specified with sendto. Jean II */
|
/* Check if an address was specified with sendto. Jean II */
|
||||||
if (msg->msg_name) {
|
if (msg->msg_name) {
|
||||||
struct sockaddr_irda *addr = (struct sockaddr_irda *) msg->msg_name;
|
struct sockaddr_irda *addr = (struct sockaddr_irda *) msg->msg_name;
|
||||||
|
err = -EINVAL;
|
||||||
/* Check address, extract pid. Jean II */
|
/* Check address, extract pid. Jean II */
|
||||||
if (msg->msg_namelen < sizeof(*addr))
|
if (msg->msg_namelen < sizeof(*addr))
|
||||||
return -EINVAL;
|
goto out;
|
||||||
if (addr->sir_family != AF_IRDA)
|
if (addr->sir_family != AF_IRDA)
|
||||||
return -EINVAL;
|
goto out;
|
||||||
|
|
||||||
pid = addr->sir_lsap_sel;
|
pid = addr->sir_lsap_sel;
|
||||||
if (pid & 0x80) {
|
if (pid & 0x80) {
|
||||||
IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__);
|
IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__);
|
||||||
return -EOPNOTSUPP;
|
err = -EOPNOTSUPP;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Check that the socket is properly bound to an Ultra
|
/* Check that the socket is properly bound to an Ultra
|
||||||
@ -1612,7 +1691,8 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
|
|||||||
(sk->sk_state != TCP_ESTABLISHED)) {
|
(sk->sk_state != TCP_ESTABLISHED)) {
|
||||||
IRDA_DEBUG(0, "%s(), socket not bound to Ultra PID.\n",
|
IRDA_DEBUG(0, "%s(), socket not bound to Ultra PID.\n",
|
||||||
__func__);
|
__func__);
|
||||||
return -ENOTCONN;
|
err = -ENOTCONN;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
/* Use PID from socket */
|
/* Use PID from socket */
|
||||||
bound = 1;
|
bound = 1;
|
||||||
@ -1631,8 +1711,9 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
|
|||||||
|
|
||||||
skb = sock_alloc_send_skb(sk, len + self->max_header_size,
|
skb = sock_alloc_send_skb(sk, len + self->max_header_size,
|
||||||
msg->msg_flags & MSG_DONTWAIT, &err);
|
msg->msg_flags & MSG_DONTWAIT, &err);
|
||||||
|
err = -ENOBUFS;
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return -ENOBUFS;
|
goto out;
|
||||||
|
|
||||||
skb_reserve(skb, self->max_header_size);
|
skb_reserve(skb, self->max_header_size);
|
||||||
skb_reset_transport_header(skb);
|
skb_reset_transport_header(skb);
|
||||||
@ -1642,16 +1723,16 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
|
|||||||
err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
|
err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
|
||||||
if (err) {
|
if (err) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = irlmp_connless_data_request((bound ? self->lsap : NULL),
|
err = irlmp_connless_data_request((bound ? self->lsap : NULL),
|
||||||
skb, pid);
|
skb, pid);
|
||||||
if (err) {
|
if (err)
|
||||||
IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
|
IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err);
|
||||||
return err;
|
out:
|
||||||
}
|
unlock_kernel();
|
||||||
return len;
|
return err ? : len;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IRDA_ULTRA */
|
#endif /* CONFIG_IRDA_ULTRA */
|
||||||
|
|
||||||
@ -1665,6 +1746,8 @@ static int irda_shutdown(struct socket *sock, int how)
|
|||||||
|
|
||||||
IRDA_DEBUG(1, "%s(%p)\n", __func__, self);
|
IRDA_DEBUG(1, "%s(%p)\n", __func__, self);
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
|
||||||
sk->sk_state = TCP_CLOSE;
|
sk->sk_state = TCP_CLOSE;
|
||||||
sk->sk_shutdown |= SEND_SHUTDOWN;
|
sk->sk_shutdown |= SEND_SHUTDOWN;
|
||||||
sk->sk_state_change(sk);
|
sk->sk_state_change(sk);
|
||||||
@ -1685,6 +1768,8 @@ static int irda_shutdown(struct socket *sock, int how)
|
|||||||
self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */
|
self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */
|
||||||
self->saddr = 0x0; /* so IrLMP assign us any link */
|
self->saddr = 0x0; /* so IrLMP assign us any link */
|
||||||
|
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1700,6 +1785,7 @@ static unsigned int irda_poll(struct file * file, struct socket *sock,
|
|||||||
|
|
||||||
IRDA_DEBUG(4, "%s()\n", __func__);
|
IRDA_DEBUG(4, "%s()\n", __func__);
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
poll_wait(file, sk->sk_sleep, wait);
|
poll_wait(file, sk->sk_sleep, wait);
|
||||||
mask = 0;
|
mask = 0;
|
||||||
|
|
||||||
@ -1747,18 +1833,34 @@ static unsigned int irda_poll(struct file * file, struct socket *sock,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
unlock_kernel();
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int irda_datagram_poll(struct file *file, struct socket *sock,
|
||||||
|
poll_table *wait)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
err = datagram_poll(file, sock, wait);
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function irda_ioctl (sock, cmd, arg)
|
* Function irda_ioctl (sock, cmd, arg)
|
||||||
*/
|
*/
|
||||||
static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
|
int err;
|
||||||
|
|
||||||
IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd);
|
IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd);
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
err = -EINVAL;
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case TIOCOUTQ: {
|
case TIOCOUTQ: {
|
||||||
long amount;
|
long amount;
|
||||||
@ -1766,9 +1868,8 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|||||||
amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
|
amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
|
||||||
if (amount < 0)
|
if (amount < 0)
|
||||||
amount = 0;
|
amount = 0;
|
||||||
if (put_user(amount, (unsigned int __user *)arg))
|
err = put_user(amount, (unsigned int __user *)arg);
|
||||||
return -EFAULT;
|
break;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case TIOCINQ: {
|
case TIOCINQ: {
|
||||||
@ -1777,15 +1878,14 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|||||||
/* These two are safe on a single CPU system as only user tasks fiddle here */
|
/* These two are safe on a single CPU system as only user tasks fiddle here */
|
||||||
if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
|
if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
|
||||||
amount = skb->len;
|
amount = skb->len;
|
||||||
if (put_user(amount, (unsigned int __user *)arg))
|
err = put_user(amount, (unsigned int __user *)arg);
|
||||||
return -EFAULT;
|
break;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case SIOCGSTAMP:
|
case SIOCGSTAMP:
|
||||||
if (sk != NULL)
|
if (sk != NULL)
|
||||||
return sock_get_timestamp(sk, (struct timeval __user *)arg);
|
err = sock_get_timestamp(sk, (struct timeval __user *)arg);
|
||||||
return -EINVAL;
|
break;
|
||||||
|
|
||||||
case SIOCGIFADDR:
|
case SIOCGIFADDR:
|
||||||
case SIOCSIFADDR:
|
case SIOCSIFADDR:
|
||||||
@ -1797,14 +1897,14 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|||||||
case SIOCSIFNETMASK:
|
case SIOCSIFNETMASK:
|
||||||
case SIOCGIFMETRIC:
|
case SIOCGIFMETRIC:
|
||||||
case SIOCSIFMETRIC:
|
case SIOCSIFMETRIC:
|
||||||
return -EINVAL;
|
break;
|
||||||
default:
|
default:
|
||||||
IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__);
|
IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__);
|
||||||
return -ENOIOCTLCMD;
|
err = -ENOIOCTLCMD;
|
||||||
}
|
}
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
/*NOTREACHED*/
|
return err;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
@ -1826,7 +1926,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
|
|||||||
* Set some options for the socket
|
* Set some options for the socket
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int irda_setsockopt(struct socket *sock, int level, int optname,
|
static int __irda_setsockopt(struct socket *sock, int level, int optname,
|
||||||
char __user *optval, unsigned int optlen)
|
char __user *optval, unsigned int optlen)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
@ -2084,6 +2184,18 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int irda_setsockopt(struct socket *sock, int level, int optname,
|
||||||
|
char __user *optval, unsigned int optlen)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
err = __irda_setsockopt(sock, level, optname, optval, optlen);
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function irda_extract_ias_value(ias_opt, ias_value)
|
* Function irda_extract_ias_value(ias_opt, ias_value)
|
||||||
*
|
*
|
||||||
@ -2136,7 +2248,7 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt,
|
|||||||
/*
|
/*
|
||||||
* Function irda_getsockopt (sock, level, optname, optval, optlen)
|
* Function irda_getsockopt (sock, level, optname, optval, optlen)
|
||||||
*/
|
*/
|
||||||
static int irda_getsockopt(struct socket *sock, int level, int optname,
|
static int __irda_getsockopt(struct socket *sock, int level, int optname,
|
||||||
char __user *optval, int __user *optlen)
|
char __user *optval, int __user *optlen)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
@ -2464,13 +2576,25 @@ bed:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int irda_getsockopt(struct socket *sock, int level, int optname,
|
||||||
|
char __user *optval, int __user *optlen)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
err = __irda_getsockopt(sock, level, optname, optval, optlen);
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct net_proto_family irda_family_ops = {
|
static const struct net_proto_family irda_family_ops = {
|
||||||
.family = PF_IRDA,
|
.family = PF_IRDA,
|
||||||
.create = irda_create,
|
.create = irda_create,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
|
static const struct proto_ops irda_stream_ops = {
|
||||||
.family = PF_IRDA,
|
.family = PF_IRDA,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.release = irda_release,
|
.release = irda_release,
|
||||||
@ -2494,7 +2618,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
|
|||||||
.sendpage = sock_no_sendpage,
|
.sendpage = sock_no_sendpage,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
|
static const struct proto_ops irda_seqpacket_ops = {
|
||||||
.family = PF_IRDA,
|
.family = PF_IRDA,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.release = irda_release,
|
.release = irda_release,
|
||||||
@ -2503,7 +2627,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
|
|||||||
.socketpair = sock_no_socketpair,
|
.socketpair = sock_no_socketpair,
|
||||||
.accept = irda_accept,
|
.accept = irda_accept,
|
||||||
.getname = irda_getname,
|
.getname = irda_getname,
|
||||||
.poll = datagram_poll,
|
.poll = irda_datagram_poll,
|
||||||
.ioctl = irda_ioctl,
|
.ioctl = irda_ioctl,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
.compat_ioctl = irda_compat_ioctl,
|
.compat_ioctl = irda_compat_ioctl,
|
||||||
@ -2518,7 +2642,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
|
|||||||
.sendpage = sock_no_sendpage,
|
.sendpage = sock_no_sendpage,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
|
static const struct proto_ops irda_dgram_ops = {
|
||||||
.family = PF_IRDA,
|
.family = PF_IRDA,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.release = irda_release,
|
.release = irda_release,
|
||||||
@ -2527,7 +2651,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
|
|||||||
.socketpair = sock_no_socketpair,
|
.socketpair = sock_no_socketpair,
|
||||||
.accept = irda_accept,
|
.accept = irda_accept,
|
||||||
.getname = irda_getname,
|
.getname = irda_getname,
|
||||||
.poll = datagram_poll,
|
.poll = irda_datagram_poll,
|
||||||
.ioctl = irda_ioctl,
|
.ioctl = irda_ioctl,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
.compat_ioctl = irda_compat_ioctl,
|
.compat_ioctl = irda_compat_ioctl,
|
||||||
@ -2543,7 +2667,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_IRDA_ULTRA
|
#ifdef CONFIG_IRDA_ULTRA
|
||||||
static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
|
static const struct proto_ops irda_ultra_ops = {
|
||||||
.family = PF_IRDA,
|
.family = PF_IRDA,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.release = irda_release,
|
.release = irda_release,
|
||||||
@ -2552,7 +2676,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
|
|||||||
.socketpair = sock_no_socketpair,
|
.socketpair = sock_no_socketpair,
|
||||||
.accept = sock_no_accept,
|
.accept = sock_no_accept,
|
||||||
.getname = irda_getname,
|
.getname = irda_getname,
|
||||||
.poll = datagram_poll,
|
.poll = irda_datagram_poll,
|
||||||
.ioctl = irda_ioctl,
|
.ioctl = irda_ioctl,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
.compat_ioctl = irda_compat_ioctl,
|
.compat_ioctl = irda_compat_ioctl,
|
||||||
@ -2568,13 +2692,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
|
|||||||
};
|
};
|
||||||
#endif /* CONFIG_IRDA_ULTRA */
|
#endif /* CONFIG_IRDA_ULTRA */
|
||||||
|
|
||||||
SOCKOPS_WRAP(irda_stream, PF_IRDA);
|
|
||||||
SOCKOPS_WRAP(irda_seqpacket, PF_IRDA);
|
|
||||||
SOCKOPS_WRAP(irda_dgram, PF_IRDA);
|
|
||||||
#ifdef CONFIG_IRDA_ULTRA
|
|
||||||
SOCKOPS_WRAP(irda_ultra, PF_IRDA);
|
|
||||||
#endif /* CONFIG_IRDA_ULTRA */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function irsock_init (pro)
|
* Function irsock_init (pro)
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user