diff options
Diffstat (limited to 'net/atm/common.c')
-rw-r--r-- | net/atm/common.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/net/atm/common.c b/net/atm/common.c index 14ff9fe39989..b4b44dbed645 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -214,6 +214,26 @@ void vcc_release_async(struct atm_vcc *vcc, int reply) | |||
214 | } | 214 | } |
215 | EXPORT_SYMBOL(vcc_release_async); | 215 | EXPORT_SYMBOL(vcc_release_async); |
216 | 216 | ||
217 | void vcc_process_recv_queue(struct atm_vcc *vcc) | ||
218 | { | ||
219 | struct sk_buff_head queue, *rq; | ||
220 | struct sk_buff *skb, *tmp; | ||
221 | unsigned long flags; | ||
222 | |||
223 | __skb_queue_head_init(&queue); | ||
224 | rq = &sk_atm(vcc)->sk_receive_queue; | ||
225 | |||
226 | spin_lock_irqsave(&rq->lock, flags); | ||
227 | skb_queue_splice_init(rq, &queue); | ||
228 | spin_unlock_irqrestore(&rq->lock, flags); | ||
229 | |||
230 | skb_queue_walk_safe(&queue, skb, tmp) { | ||
231 | __skb_unlink(skb, &queue); | ||
232 | vcc->push(vcc, skb); | ||
233 | } | ||
234 | } | ||
235 | EXPORT_SYMBOL(vcc_process_recv_queue); | ||
236 | |||
217 | void atm_dev_signal_change(struct atm_dev *dev, char signal) | 237 | void atm_dev_signal_change(struct atm_dev *dev, char signal) |
218 | { | 238 | { |
219 | pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n", | 239 | pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n", |
@@ -502,8 +522,11 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
502 | 522 | ||
503 | if (sock->state != SS_CONNECTED) | 523 | if (sock->state != SS_CONNECTED) |
504 | return -ENOTCONN; | 524 | return -ENOTCONN; |
505 | if (flags & ~MSG_DONTWAIT) /* only handle MSG_DONTWAIT */ | 525 | |
526 | /* only handle MSG_DONTWAIT and MSG_PEEK */ | ||
527 | if (flags & ~(MSG_DONTWAIT | MSG_PEEK)) | ||
506 | return -EOPNOTSUPP; | 528 | return -EOPNOTSUPP; |
529 | |||
507 | vcc = ATM_SD(sock); | 530 | vcc = ATM_SD(sock); |
508 | if (test_bit(ATM_VF_RELEASED, &vcc->flags) || | 531 | if (test_bit(ATM_VF_RELEASED, &vcc->flags) || |
509 | test_bit(ATM_VF_CLOSE, &vcc->flags) || | 532 | test_bit(ATM_VF_CLOSE, &vcc->flags) || |
@@ -524,8 +547,13 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
524 | if (error) | 547 | if (error) |
525 | return error; | 548 | return error; |
526 | sock_recv_ts_and_drops(msg, sk, skb); | 549 | sock_recv_ts_and_drops(msg, sk, skb); |
527 | pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc), skb->truesize); | 550 | |
528 | atm_return(vcc, skb->truesize); | 551 | if (!(flags & MSG_PEEK)) { |
552 | pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc), | ||
553 | skb->truesize); | ||
554 | atm_return(vcc, skb->truesize); | ||
555 | } | ||
556 | |||
529 | skb_free_datagram(sk, skb); | 557 | skb_free_datagram(sk, skb); |
530 | return copied; | 558 | return copied; |
531 | } | 559 | } |