diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 14:47:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 14:47:02 -0400 |
commit | 5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0 (patch) | |
tree | 7851ef1c93aa1aba7ef327ca4b75fd35e6d10f29 /net/bluetooth/af_bluetooth.c | |
parent | 02f36038c568111ad4fc433f6fa760ff5e38fab4 (diff) | |
parent | ec37a48d1d16c30b655ac5280209edf52a6775d4 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1699 commits)
bnx2/bnx2x: Unsupported Ethtool operations should return -EINVAL.
vlan: Calling vlan_hwaccel_do_receive() is always valid.
tproxy: use the interface primary IP address as a default value for --on-ip
tproxy: added IPv6 support to the socket match
cxgb3: function namespace cleanup
tproxy: added IPv6 support to the TPROXY target
tproxy: added IPv6 socket lookup function to nf_tproxy_core
be2net: Changes to use only priority codes allowed by f/w
tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled
tproxy: added tproxy sockopt interface in the IPV6 layer
tproxy: added udp6_lib_lookup function
tproxy: added const specifiers to udp lookup functions
tproxy: split off ipv6 defragmentation to a separate module
l2tp: small cleanup
nf_nat: restrict ICMP translation for embedded header
can: mcp251x: fix generation of error frames
can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set
can-raw: add msg_flags to distinguish local traffic
9p: client code cleanup
rds: make local functions/variables static
...
Fix up conflicts in net/core/dev.c, drivers/net/pcmcia/smc91c92_cs.c and
drivers/net/wireless/ath/ath9k/debug.c as per David
Diffstat (limited to 'net/bluetooth/af_bluetooth.c')
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 114 |
1 files changed, 111 insertions, 3 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 421c45bd1b95..c4cf3f595004 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -265,6 +265,115 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
265 | } | 265 | } |
266 | EXPORT_SYMBOL(bt_sock_recvmsg); | 266 | EXPORT_SYMBOL(bt_sock_recvmsg); |
267 | 267 | ||
268 | static long bt_sock_data_wait(struct sock *sk, long timeo) | ||
269 | { | ||
270 | DECLARE_WAITQUEUE(wait, current); | ||
271 | |||
272 | add_wait_queue(sk_sleep(sk), &wait); | ||
273 | for (;;) { | ||
274 | set_current_state(TASK_INTERRUPTIBLE); | ||
275 | |||
276 | if (!skb_queue_empty(&sk->sk_receive_queue)) | ||
277 | break; | ||
278 | |||
279 | if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
280 | break; | ||
281 | |||
282 | if (signal_pending(current) || !timeo) | ||
283 | break; | ||
284 | |||
285 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | ||
286 | release_sock(sk); | ||
287 | timeo = schedule_timeout(timeo); | ||
288 | lock_sock(sk); | ||
289 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | ||
290 | } | ||
291 | |||
292 | __set_current_state(TASK_RUNNING); | ||
293 | remove_wait_queue(sk_sleep(sk), &wait); | ||
294 | return timeo; | ||
295 | } | ||
296 | |||
297 | int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | ||
298 | struct msghdr *msg, size_t size, int flags) | ||
299 | { | ||
300 | struct sock *sk = sock->sk; | ||
301 | int err = 0; | ||
302 | size_t target, copied = 0; | ||
303 | long timeo; | ||
304 | |||
305 | if (flags & MSG_OOB) | ||
306 | return -EOPNOTSUPP; | ||
307 | |||
308 | msg->msg_namelen = 0; | ||
309 | |||
310 | BT_DBG("sk %p size %zu", sk, size); | ||
311 | |||
312 | lock_sock(sk); | ||
313 | |||
314 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); | ||
315 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | ||
316 | |||
317 | do { | ||
318 | struct sk_buff *skb; | ||
319 | int chunk; | ||
320 | |||
321 | skb = skb_dequeue(&sk->sk_receive_queue); | ||
322 | if (!skb) { | ||
323 | if (copied >= target) | ||
324 | break; | ||
325 | |||
326 | if ((err = sock_error(sk)) != 0) | ||
327 | break; | ||
328 | if (sk->sk_shutdown & RCV_SHUTDOWN) | ||
329 | break; | ||
330 | |||
331 | err = -EAGAIN; | ||
332 | if (!timeo) | ||
333 | break; | ||
334 | |||
335 | timeo = bt_sock_data_wait(sk, timeo); | ||
336 | |||
337 | if (signal_pending(current)) { | ||
338 | err = sock_intr_errno(timeo); | ||
339 | goto out; | ||
340 | } | ||
341 | continue; | ||
342 | } | ||
343 | |||
344 | chunk = min_t(unsigned int, skb->len, size); | ||
345 | if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { | ||
346 | skb_queue_head(&sk->sk_receive_queue, skb); | ||
347 | if (!copied) | ||
348 | copied = -EFAULT; | ||
349 | break; | ||
350 | } | ||
351 | copied += chunk; | ||
352 | size -= chunk; | ||
353 | |||
354 | sock_recv_ts_and_drops(msg, sk, skb); | ||
355 | |||
356 | if (!(flags & MSG_PEEK)) { | ||
357 | skb_pull(skb, chunk); | ||
358 | if (skb->len) { | ||
359 | skb_queue_head(&sk->sk_receive_queue, skb); | ||
360 | break; | ||
361 | } | ||
362 | kfree_skb(skb); | ||
363 | |||
364 | } else { | ||
365 | /* put message back and return */ | ||
366 | skb_queue_head(&sk->sk_receive_queue, skb); | ||
367 | break; | ||
368 | } | ||
369 | } while (size); | ||
370 | |||
371 | out: | ||
372 | release_sock(sk); | ||
373 | return copied ? : err; | ||
374 | } | ||
375 | EXPORT_SYMBOL(bt_sock_stream_recvmsg); | ||
376 | |||
268 | static inline unsigned int bt_accept_poll(struct sock *parent) | 377 | static inline unsigned int bt_accept_poll(struct sock *parent) |
269 | { | 378 | { |
270 | struct list_head *p, *n; | 379 | struct list_head *p, *n; |
@@ -297,13 +406,12 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w | |||
297 | mask |= POLLERR; | 406 | mask |= POLLERR; |
298 | 407 | ||
299 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 408 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
300 | mask |= POLLRDHUP; | 409 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; |
301 | 410 | ||
302 | if (sk->sk_shutdown == SHUTDOWN_MASK) | 411 | if (sk->sk_shutdown == SHUTDOWN_MASK) |
303 | mask |= POLLHUP; | 412 | mask |= POLLHUP; |
304 | 413 | ||
305 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 414 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
306 | (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
307 | mask |= POLLIN | POLLRDNORM; | 415 | mask |= POLLIN | POLLRDNORM; |
308 | 416 | ||
309 | if (sk->sk_state == BT_CLOSED) | 417 | if (sk->sk_state == BT_CLOSED) |