Commit da0fc845 authored by Chas Williams's avatar Chas Williams Committed by Hideaki Yoshifuji

[ATM]: Replace vcc->reply with sk->sk_err; implement sk_write_space.

parent f5f8f4a9
...@@ -90,7 +90,7 @@ static int atmtcp_recv_control(const struct atmtcp_control *msg) ...@@ -90,7 +90,7 @@ static int atmtcp_recv_control(const struct atmtcp_control *msg)
vcc->vpi = msg->addr.sap_addr.vpi; vcc->vpi = msg->addr.sap_addr.vpi;
vcc->vci = msg->addr.sap_addr.vci; vcc->vci = msg->addr.sap_addr.vci;
vcc->qos = msg->qos; vcc->qos = msg->qos;
vcc->reply = msg->result; vcc->sk->sk_err = -msg->result;
switch (msg->type) { switch (msg->type) {
case ATMTCP_CTRL_OPEN: case ATMTCP_CTRL_OPEN:
change_bit(ATM_VF_READY,&vcc->flags); change_bit(ATM_VF_READY,&vcc->flags);
...@@ -134,7 +134,7 @@ static int atmtcp_v_open(struct atm_vcc *vcc,short vpi,int vci) ...@@ -134,7 +134,7 @@ static int atmtcp_v_open(struct atm_vcc *vcc,short vpi,int vci)
clear_bit(ATM_VF_READY,&vcc->flags); /* just in case ... */ clear_bit(ATM_VF_READY,&vcc->flags); /* just in case ... */
error = atmtcp_send_control(vcc,ATMTCP_CTRL_OPEN,&msg,ATM_VF_READY); error = atmtcp_send_control(vcc,ATMTCP_CTRL_OPEN,&msg,ATM_VF_READY);
if (error) return error; if (error) return error;
return vcc->reply; return -vcc->sk->sk_err;
} }
......
...@@ -252,6 +252,7 @@ enum { ...@@ -252,6 +252,7 @@ enum {
ATM_VF_SESSION, /* VCC is p2mp session control descriptor */ ATM_VF_SESSION, /* VCC is p2mp session control descriptor */
ATM_VF_HASSAP, /* SAP has been set */ ATM_VF_HASSAP, /* SAP has been set */
ATM_VF_CLOSE, /* asynchronous close - treat like VF_RELEASED*/ ATM_VF_CLOSE, /* asynchronous close - treat like VF_RELEASED*/
ATM_VF_WAITING, /* waiting for reply from sigd */
}; };
...@@ -296,7 +297,6 @@ struct atm_vcc { ...@@ -296,7 +297,6 @@ struct atm_vcc {
short itf; /* interface number */ short itf; /* interface number */
struct sockaddr_atmsvc local; struct sockaddr_atmsvc local;
struct sockaddr_atmsvc remote; struct sockaddr_atmsvc remote;
int reply; /* also used by ATMTCP */
/* Multipoint part ------------------------------------------------- */ /* Multipoint part ------------------------------------------------- */
struct atm_vcc *session; /* session VCC descriptor */ struct atm_vcc *session; /* session VCC descriptor */
/* Other stuff ----------------------------------------------------- */ /* Other stuff ----------------------------------------------------- */
......
...@@ -243,6 +243,29 @@ static void vcc_def_wakeup(struct sock *sk) ...@@ -243,6 +243,29 @@ static void vcc_def_wakeup(struct sock *sk)
wake_up(sk->sk_sleep); wake_up(sk->sk_sleep);
read_unlock(&sk->sk_callback_lock); read_unlock(&sk->sk_callback_lock);
} }
static inline int vcc_writable(struct sock *sk)
{
struct atm_vcc *vcc = atm_sk(sk);
return (vcc->qos.txtp.max_sdu +
atomic_read(&sk->sk_wmem_alloc)) <= sk->sk_sndbuf;
}
static void vcc_write_space(struct sock *sk)
{
read_lock(&sk->sk_callback_lock);
if (vcc_writable(sk)) {
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
wake_up_interruptible(sk->sk_sleep);
sk_wake_async(sk, 2, POLL_OUT);
}
read_unlock(&sk->sk_callback_lock);
}
int vcc_create(struct socket *sock, int protocol, int family) int vcc_create(struct socket *sock, int protocol, int family)
{ {
...@@ -257,6 +280,7 @@ int vcc_create(struct socket *sock, int protocol, int family) ...@@ -257,6 +280,7 @@ int vcc_create(struct socket *sock, int protocol, int family)
return -ENOMEM; return -ENOMEM;
sock_init_data(sock, sk); sock_init_data(sock, sk);
sk->sk_state_change = vcc_def_wakeup; sk->sk_state_change = vcc_def_wakeup;
sk->sk_write_space = vcc_write_space;
vcc = atm_sk(sk) = kmalloc(sizeof(*vcc), GFP_KERNEL); vcc = atm_sk(sk) = kmalloc(sizeof(*vcc), GFP_KERNEL);
if (!vcc) { if (!vcc) {
...@@ -326,8 +350,8 @@ int vcc_release(struct socket *sock) ...@@ -326,8 +350,8 @@ int vcc_release(struct socket *sock)
void vcc_release_async(struct atm_vcc *vcc, int reply) void vcc_release_async(struct atm_vcc *vcc, int reply)
{ {
set_bit(ATM_VF_CLOSE, &vcc->flags); set_bit(ATM_VF_CLOSE, &vcc->flags);
vcc->reply = reply;
vcc->sk->sk_err = -reply; vcc->sk->sk_err = -reply;
clear_bit(ATM_VF_WAITING, &vcc->flags);
vcc->sk->sk_state_change(vcc->sk); vcc->sk->sk_state_change(vcc->sk);
} }
...@@ -501,7 +525,7 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, ...@@ -501,7 +525,7 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
vcc = ATM_SD(sock); vcc = ATM_SD(sock);
if (test_bit(ATM_VF_RELEASED,&vcc->flags) || if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
test_bit(ATM_VF_CLOSE,&vcc->flags)) test_bit(ATM_VF_CLOSE,&vcc->flags))
return vcc->reply; return -sk->sk_err;
if (!test_bit(ATM_VF_READY, &vcc->flags)) if (!test_bit(ATM_VF_READY, &vcc->flags))
return 0; return 0;
...@@ -558,7 +582,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, ...@@ -558,7 +582,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
vcc = ATM_SD(sock); vcc = ATM_SD(sock);
if (test_bit(ATM_VF_RELEASED, &vcc->flags) || if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
test_bit(ATM_VF_CLOSE, &vcc->flags)) { test_bit(ATM_VF_CLOSE, &vcc->flags)) {
error = vcc->reply; error = -sk->sk_err;
goto out; goto out;
} }
if (!test_bit(ATM_VF_READY, &vcc->flags)) { if (!test_bit(ATM_VF_READY, &vcc->flags)) {
...@@ -589,7 +613,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, ...@@ -589,7 +613,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
} }
if (test_bit(ATM_VF_RELEASED,&vcc->flags) || if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
test_bit(ATM_VF_CLOSE,&vcc->flags)) { test_bit(ATM_VF_CLOSE,&vcc->flags)) {
error = vcc->reply; error = -sk->sk_err;
break; break;
} }
if (!test_bit(ATM_VF_READY,&vcc->flags)) { if (!test_bit(ATM_VF_READY,&vcc->flags)) {
...@@ -617,29 +641,38 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, ...@@ -617,29 +641,38 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
} }
unsigned int atm_poll(struct file *file,struct socket *sock,poll_table *wait) unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
{ {
struct sock *sk = sock->sk;
struct atm_vcc *vcc; struct atm_vcc *vcc;
unsigned int mask; unsigned int mask;
vcc = ATM_SD(sock); poll_wait(file, sk->sk_sleep, wait);
poll_wait(file, vcc->sk->sk_sleep, wait);
mask = 0; mask = 0;
if (skb_peek(&vcc->sk->sk_receive_queue))
mask |= POLLIN | POLLRDNORM; vcc = ATM_SD(sock);
if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
test_bit(ATM_VF_CLOSE,&vcc->flags)) /* exceptional events */
if (sk->sk_err)
mask = POLLERR;
if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
test_bit(ATM_VF_CLOSE, &vcc->flags))
mask |= POLLHUP; mask |= POLLHUP;
if (sock->state != SS_CONNECTING) {
if (vcc->qos.txtp.traffic_class != ATM_NONE && /* readable? */
vcc->qos.txtp.max_sdu + if (!skb_queue_empty(&sk->sk_receive_queue))
atomic_read(&vcc->sk->sk_wmem_alloc) <= vcc->sk->sk_sndbuf) mask |= POLLIN | POLLRDNORM;
mask |= POLLOUT | POLLWRNORM;
} /* writable? */
else if (vcc->reply != WAITING) { if (sock->state == SS_CONNECTING &&
mask |= POLLOUT | POLLWRNORM; test_bit(ATM_VF_WAITING, &vcc->flags))
if (vcc->reply) mask |= POLLERR; return mask;
}
if (vcc->qos.txtp.traffic_class != ATM_NONE &&
vcc_writable(vcc->sk))
mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
return mask; return mask;
} }
......
...@@ -17,7 +17,7 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, ...@@ -17,7 +17,7 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
int size, int flags); int size, int flags);
int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
int total_len); int total_len);
unsigned int atm_poll(struct file *file,struct socket *sock,poll_table *wait); unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait);
int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int vcc_setsockopt(struct socket *sock, int level, int optname, char *optval, int vcc_setsockopt(struct socket *sock, int level, int optname, char *optval,
int optlen); int optlen);
......
...@@ -224,7 +224,7 @@ static void vc_info(struct atm_vcc *vcc,char *buf) ...@@ -224,7 +224,7 @@ static void vc_info(struct atm_vcc *vcc,char *buf)
here += sprintf(here, "%3d", vcc->sk->sk_family); here += sprintf(here, "%3d", vcc->sk->sk_family);
} }
here += sprintf(here," %04lx %5d %7d/%7d %7d/%7d\n",vcc->flags, here += sprintf(here," %04lx %5d %7d/%7d %7d/%7d\n",vcc->flags,
vcc->reply, vcc->sk->sk_err,
atomic_read(&vcc->sk->sk_wmem_alloc), vcc->sk->sk_sndbuf, atomic_read(&vcc->sk->sk_wmem_alloc), vcc->sk->sk_sndbuf,
atomic_read(&vcc->sk->sk_rmem_alloc), vcc->sk->sk_rcvbuf); atomic_read(&vcc->sk->sk_rmem_alloc), vcc->sk->sk_rcvbuf);
} }
......
...@@ -111,7 +111,7 @@ static struct proto_ops pvc_proto_ops = { ...@@ -111,7 +111,7 @@ static struct proto_ops pvc_proto_ops = {
.socketpair = sock_no_socketpair, .socketpair = sock_no_socketpair,
.accept = sock_no_accept, .accept = sock_no_accept,
.getname = pvc_getname, .getname = pvc_getname,
.poll = atm_poll, .poll = vcc_poll,
.ioctl = vcc_ioctl, .ioctl = vcc_ioctl,
.listen = sock_no_listen, .listen = sock_no_listen,
.shutdown = pvc_shutdown, .shutdown = pvc_shutdown,
......
...@@ -40,7 +40,7 @@ static void atm_pop_raw(struct atm_vcc *vcc,struct sk_buff *skb) ...@@ -40,7 +40,7 @@ static void atm_pop_raw(struct atm_vcc *vcc,struct sk_buff *skb)
skb->truesize); skb->truesize);
atomic_sub(skb->truesize, &vcc->sk->sk_wmem_alloc); atomic_sub(skb->truesize, &vcc->sk->sk_wmem_alloc);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
wake_up(vcc->sk->sk_sleep); vcc->sk->sk_write_space(vcc->sk);
} }
......
...@@ -103,7 +103,8 @@ static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb) ...@@ -103,7 +103,8 @@ static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb)
vcc = *(struct atm_vcc **) &msg->vcc; vcc = *(struct atm_vcc **) &msg->vcc;
switch (msg->type) { switch (msg->type) {
case as_okay: case as_okay:
vcc->reply = msg->reply; vcc->sk->sk_err = -msg->reply;
clear_bit(ATM_VF_WAITING, &vcc->flags);
if (!*vcc->local.sas_addr.prv && if (!*vcc->local.sas_addr.prv &&
!*vcc->local.sas_addr.pub) { !*vcc->local.sas_addr.pub) {
vcc->local.sas_family = AF_ATMSVC; vcc->local.sas_family = AF_ATMSVC;
...@@ -123,8 +124,8 @@ static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb) ...@@ -123,8 +124,8 @@ static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb)
case as_error: case as_error:
clear_bit(ATM_VF_REGIS,&vcc->flags); clear_bit(ATM_VF_REGIS,&vcc->flags);
clear_bit(ATM_VF_READY,&vcc->flags); clear_bit(ATM_VF_READY,&vcc->flags);
vcc->reply = msg->reply;
vcc->sk->sk_err = -msg->reply; vcc->sk->sk_err = -msg->reply;
clear_bit(ATM_VF_WAITING, &vcc->flags);
break; break;
case as_indicate: case as_indicate:
vcc = *(struct atm_vcc **) &msg->listen_vcc; vcc = *(struct atm_vcc **) &msg->listen_vcc;
...@@ -145,8 +146,8 @@ static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb) ...@@ -145,8 +146,8 @@ static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb)
case as_close: case as_close:
set_bit(ATM_VF_RELEASED,&vcc->flags); set_bit(ATM_VF_RELEASED,&vcc->flags);
clear_bit(ATM_VF_READY,&vcc->flags); clear_bit(ATM_VF_READY,&vcc->flags);
vcc->reply = msg->reply;
vcc->sk->sk_err = -msg->reply; vcc->sk->sk_err = -msg->reply;
clear_bit(ATM_VF_WAITING, &vcc->flags);
break; break;
case as_modify: case as_modify:
modify_qos(vcc,msg); modify_qos(vcc,msg);
...@@ -202,8 +203,8 @@ static void purge_vcc(struct atm_vcc *vcc) ...@@ -202,8 +203,8 @@ static void purge_vcc(struct atm_vcc *vcc)
if (vcc->sk->sk_family == PF_ATMSVC && if (vcc->sk->sk_family == PF_ATMSVC &&
!test_bit(ATM_VF_META,&vcc->flags)) { !test_bit(ATM_VF_META,&vcc->flags)) {
set_bit(ATM_VF_RELEASED,&vcc->flags); set_bit(ATM_VF_RELEASED,&vcc->flags);
vcc->reply = -EUNATCH;
vcc->sk->sk_err = EUNATCH; vcc->sk->sk_err = EUNATCH;
clear_bit(ATM_VF_WAITING, &vcc->flags);
vcc->sk->sk_state_change(vcc->sk); vcc->sk->sk_state_change(vcc->sk);
} }
} }
......
...@@ -11,9 +11,6 @@ ...@@ -11,9 +11,6 @@
#include <linux/atmsvc.h> #include <linux/atmsvc.h>
#define WAITING 1 /* for reply: 0: no error, < 0: error, ... */
extern struct atm_vcc *sigd; /* needed in svc_release */ extern struct atm_vcc *sigd; /* needed in svc_release */
......
...@@ -137,10 +137,10 @@ static int svc_bind(struct socket *sock,struct sockaddr *sockaddr, ...@@ -137,10 +137,10 @@ static int svc_bind(struct socket *sock,struct sockaddr *sockaddr,
goto out; goto out;
} }
vcc->local = *addr; vcc->local = *addr;
vcc->reply = WAITING; set_bit(ATM_VF_WAITING, &vcc->flags);
prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local); sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local);
while (vcc->reply == WAITING && sigd) { while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
schedule(); schedule();
prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
} }
...@@ -150,9 +150,9 @@ static int svc_bind(struct socket *sock,struct sockaddr *sockaddr, ...@@ -150,9 +150,9 @@ static int svc_bind(struct socket *sock,struct sockaddr *sockaddr,
error = -EUNATCH; error = -EUNATCH;
goto out; goto out;
} }
if (!vcc->reply) if (!sk->sk_err)
set_bit(ATM_VF_BOUND,&vcc->flags); set_bit(ATM_VF_BOUND,&vcc->flags);
error = vcc->reply; error = -sk->sk_err;
out: out:
release_sock(sk); release_sock(sk);
return error; return error;
...@@ -183,13 +183,13 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr, ...@@ -183,13 +183,13 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
error = -EISCONN; error = -EISCONN;
goto out; goto out;
case SS_CONNECTING: case SS_CONNECTING:
if (vcc->reply == WAITING) { if (test_bit(ATM_VF_WAITING, &vcc->flags)) {
error = -EALREADY; error = -EALREADY;
goto out; goto out;
} }
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
if (vcc->reply) { if (sk->sk_err) {
error = vcc->reply; error = -sk->sk_err;
goto out; goto out;
} }
break; break;
...@@ -218,7 +218,7 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr, ...@@ -218,7 +218,7 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
goto out; goto out;
} }
vcc->remote = *addr; vcc->remote = *addr;
vcc->reply = WAITING; set_bit(ATM_VF_WAITING, &vcc->flags);
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
sigd_enq(vcc,as_connect,NULL,NULL,&vcc->remote); sigd_enq(vcc,as_connect,NULL,NULL,&vcc->remote);
if (flags & O_NONBLOCK) { if (flags & O_NONBLOCK) {
...@@ -228,7 +228,7 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr, ...@@ -228,7 +228,7 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
goto out; goto out;
} }
error = 0; error = 0;
while (vcc->reply == WAITING && sigd) { while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
schedule(); schedule();
if (!signal_pending(current)) { if (!signal_pending(current)) {
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
...@@ -248,11 +248,11 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr, ...@@ -248,11 +248,11 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
* Kernel <--close--- Demon * Kernel <--close--- Demon
*/ */
sigd_enq(vcc,as_close,NULL,NULL,NULL); sigd_enq(vcc,as_close,NULL,NULL,NULL);
while (vcc->reply == WAITING && sigd) { while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
schedule(); schedule();
} }
if (!vcc->reply) if (!sk->sk_err)
while (!test_bit(ATM_VF_RELEASED,&vcc->flags) while (!test_bit(ATM_VF_RELEASED,&vcc->flags)
&& sigd) { && sigd) {
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
...@@ -272,8 +272,8 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr, ...@@ -272,8 +272,8 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
error = -EUNATCH; error = -EUNATCH;
goto out; goto out;
} }
if (vcc->reply) { if (sk->sk_err) {
error = vcc->reply; error = -sk->sk_err;
goto out; goto out;
} }
} }
...@@ -311,10 +311,10 @@ static int svc_listen(struct socket *sock,int backlog) ...@@ -311,10 +311,10 @@ static int svc_listen(struct socket *sock,int backlog)
error = -EINVAL; error = -EINVAL;
goto out; goto out;
} }
vcc->reply = WAITING; set_bit(ATM_VF_WAITING, &vcc->flags);
prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local); sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
while (vcc->reply == WAITING && sigd) { while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
schedule(); schedule();
prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
} }
...@@ -326,7 +326,7 @@ static int svc_listen(struct socket *sock,int backlog) ...@@ -326,7 +326,7 @@ static int svc_listen(struct socket *sock,int backlog)
set_bit(ATM_VF_LISTEN,&vcc->flags); set_bit(ATM_VF_LISTEN,&vcc->flags);
vcc->sk->sk_max_ack_backlog = backlog > 0 ? backlog : vcc->sk->sk_max_ack_backlog = backlog > 0 ? backlog :
ATM_BACKLOG_DEFAULT; ATM_BACKLOG_DEFAULT;
error = vcc->reply; error = -sk->sk_err;
out: out:
release_sock(sk); release_sock(sk);
return error; return error;
...@@ -359,7 +359,7 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags) ...@@ -359,7 +359,7 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
sigd) { sigd) {
if (test_bit(ATM_VF_RELEASED,&old_vcc->flags)) break; if (test_bit(ATM_VF_RELEASED,&old_vcc->flags)) break;
if (test_bit(ATM_VF_CLOSE,&old_vcc->flags)) { if (test_bit(ATM_VF_CLOSE,&old_vcc->flags)) {
error = old_vcc->reply; error = -sk->sk_err;
break; break;
} }
if (flags & O_NONBLOCK) { if (flags & O_NONBLOCK) {
...@@ -399,10 +399,10 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags) ...@@ -399,10 +399,10 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
goto out; goto out;
} }
/* wait should be short, so we ignore the non-blocking flag */ /* wait should be short, so we ignore the non-blocking flag */
new_vcc->reply = WAITING; set_bit(ATM_VF_WAITING, &new_vcc->flags);
prepare_to_wait(new_vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); prepare_to_wait(new_vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL); sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL);
while (new_vcc->reply == WAITING && sigd) { while (test_bit(ATM_VF_WAITING, &new_vcc->flags) && sigd) {
release_sock(sk); release_sock(sk);
schedule(); schedule();
lock_sock(sk); lock_sock(sk);
...@@ -413,9 +413,10 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags) ...@@ -413,9 +413,10 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
error = -EUNATCH; error = -EUNATCH;
goto out; goto out;
} }
if (!new_vcc->reply) break; if (!new_vcc->sk->sk_err)
if (new_vcc->reply != -ERESTARTSYS) { break;
error = new_vcc->reply; if (new_vcc->sk->sk_err != ERESTARTSYS) {
error = -new_vcc->sk->sk_err;
goto out; goto out;
} }
} }
...@@ -443,17 +444,17 @@ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos) ...@@ -443,17 +444,17 @@ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
{ {
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
vcc->reply = WAITING; set_bit(ATM_VF_WAITING, &vcc->flags);
prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0); sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0);
while (vcc->reply == WAITING && !test_bit(ATM_VF_RELEASED,&vcc->flags) while (test_bit(ATM_VF_WAITING, &vcc->flags) &&
&& sigd) { !test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) {
schedule(); schedule();
prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
} }
finish_wait(vcc->sk->sk_sleep, &wait); finish_wait(vcc->sk->sk_sleep, &wait);
if (!sigd) return -EUNATCH; if (!sigd) return -EUNATCH;
return vcc->reply; return -vcc->sk->sk_err;
} }
...@@ -519,7 +520,7 @@ static struct proto_ops svc_proto_ops = { ...@@ -519,7 +520,7 @@ static struct proto_ops svc_proto_ops = {
.socketpair = sock_no_socketpair, .socketpair = sock_no_socketpair,
.accept = svc_accept, .accept = svc_accept,
.getname = svc_getname, .getname = svc_getname,
.poll = atm_poll, .poll = vcc_poll,
.ioctl = vcc_ioctl, .ioctl = vcc_ioctl,
.listen = svc_listen, .listen = svc_listen,
.shutdown = svc_shutdown, .shutdown = svc_shutdown,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment