diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-05-31 16:24:26 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-06-03 21:08:40 -0400 |
commit | 1c92b4e50ef926d1e26fcc056a520e4a7d12478c (patch) | |
tree | 5657e611aef30e1f994d018e23a3a8cffa38677e /net/unix | |
parent | c1a13ff57ab1ce52a0aae9984594dbfcfbaf68c0 (diff) |
[AF_UNIX]: Make socket locking much less confusing.
The unix_state_*() locking macros imply that there is some
rwlock kind of thing going on, but the implementation is
actually a spinlock which makes the code more confusing than
it needs to be.
So use plain unix_state_lock and unix_state_unlock.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix')
-rw-r--r-- | net/unix/af_unix.c | 94 |
1 files changed, 47 insertions, 47 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index fc12ba51c1fc..453ede86a65b 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -174,11 +174,11 @@ static struct sock *unix_peer_get(struct sock *s) | |||
174 | { | 174 | { |
175 | struct sock *peer; | 175 | struct sock *peer; |
176 | 176 | ||
177 | unix_state_rlock(s); | 177 | unix_state_lock(s); |
178 | peer = unix_peer(s); | 178 | peer = unix_peer(s); |
179 | if (peer) | 179 | if (peer) |
180 | sock_hold(peer); | 180 | sock_hold(peer); |
181 | unix_state_runlock(s); | 181 | unix_state_unlock(s); |
182 | return peer; | 182 | return peer; |
183 | } | 183 | } |
184 | 184 | ||
@@ -369,7 +369,7 @@ static int unix_release_sock (struct sock *sk, int embrion) | |||
369 | unix_remove_socket(sk); | 369 | unix_remove_socket(sk); |
370 | 370 | ||
371 | /* Clear state */ | 371 | /* Clear state */ |
372 | unix_state_wlock(sk); | 372 | unix_state_lock(sk); |
373 | sock_orphan(sk); | 373 | sock_orphan(sk); |
374 | sk->sk_shutdown = SHUTDOWN_MASK; | 374 | sk->sk_shutdown = SHUTDOWN_MASK; |
375 | dentry = u->dentry; | 375 | dentry = u->dentry; |
@@ -378,7 +378,7 @@ static int unix_release_sock (struct sock *sk, int embrion) | |||
378 | u->mnt = NULL; | 378 | u->mnt = NULL; |
379 | state = sk->sk_state; | 379 | state = sk->sk_state; |
380 | sk->sk_state = TCP_CLOSE; | 380 | sk->sk_state = TCP_CLOSE; |
381 | unix_state_wunlock(sk); | 381 | unix_state_unlock(sk); |
382 | 382 | ||
383 | wake_up_interruptible_all(&u->peer_wait); | 383 | wake_up_interruptible_all(&u->peer_wait); |
384 | 384 | ||
@@ -386,12 +386,12 @@ static int unix_release_sock (struct sock *sk, int embrion) | |||
386 | 386 | ||
387 | if (skpair!=NULL) { | 387 | if (skpair!=NULL) { |
388 | if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { | 388 | if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { |
389 | unix_state_wlock(skpair); | 389 | unix_state_lock(skpair); |
390 | /* No more writes */ | 390 | /* No more writes */ |
391 | skpair->sk_shutdown = SHUTDOWN_MASK; | 391 | skpair->sk_shutdown = SHUTDOWN_MASK; |
392 | if (!skb_queue_empty(&sk->sk_receive_queue) || embrion) | 392 | if (!skb_queue_empty(&sk->sk_receive_queue) || embrion) |
393 | skpair->sk_err = ECONNRESET; | 393 | skpair->sk_err = ECONNRESET; |
394 | unix_state_wunlock(skpair); | 394 | unix_state_unlock(skpair); |
395 | skpair->sk_state_change(skpair); | 395 | skpair->sk_state_change(skpair); |
396 | read_lock(&skpair->sk_callback_lock); | 396 | read_lock(&skpair->sk_callback_lock); |
397 | sk_wake_async(skpair,1,POLL_HUP); | 397 | sk_wake_async(skpair,1,POLL_HUP); |
@@ -448,7 +448,7 @@ static int unix_listen(struct socket *sock, int backlog) | |||
448 | err = -EINVAL; | 448 | err = -EINVAL; |
449 | if (!u->addr) | 449 | if (!u->addr) |
450 | goto out; /* No listens on an unbound socket */ | 450 | goto out; /* No listens on an unbound socket */ |
451 | unix_state_wlock(sk); | 451 | unix_state_lock(sk); |
452 | if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN) | 452 | if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN) |
453 | goto out_unlock; | 453 | goto out_unlock; |
454 | if (backlog > sk->sk_max_ack_backlog) | 454 | if (backlog > sk->sk_max_ack_backlog) |
@@ -462,7 +462,7 @@ static int unix_listen(struct socket *sock, int backlog) | |||
462 | err = 0; | 462 | err = 0; |
463 | 463 | ||
464 | out_unlock: | 464 | out_unlock: |
465 | unix_state_wunlock(sk); | 465 | unix_state_unlock(sk); |
466 | out: | 466 | out: |
467 | return err; | 467 | return err; |
468 | } | 468 | } |
@@ -881,7 +881,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, | |||
881 | if (!other) | 881 | if (!other) |
882 | goto out; | 882 | goto out; |
883 | 883 | ||
884 | unix_state_wlock(sk); | 884 | unix_state_lock(sk); |
885 | 885 | ||
886 | err = -EPERM; | 886 | err = -EPERM; |
887 | if (!unix_may_send(sk, other)) | 887 | if (!unix_may_send(sk, other)) |
@@ -896,7 +896,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, | |||
896 | * 1003.1g breaking connected state with AF_UNSPEC | 896 | * 1003.1g breaking connected state with AF_UNSPEC |
897 | */ | 897 | */ |
898 | other = NULL; | 898 | other = NULL; |
899 | unix_state_wlock(sk); | 899 | unix_state_lock(sk); |
900 | } | 900 | } |
901 | 901 | ||
902 | /* | 902 | /* |
@@ -905,19 +905,19 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, | |||
905 | if (unix_peer(sk)) { | 905 | if (unix_peer(sk)) { |
906 | struct sock *old_peer = unix_peer(sk); | 906 | struct sock *old_peer = unix_peer(sk); |
907 | unix_peer(sk)=other; | 907 | unix_peer(sk)=other; |
908 | unix_state_wunlock(sk); | 908 | unix_state_unlock(sk); |
909 | 909 | ||
910 | if (other != old_peer) | 910 | if (other != old_peer) |
911 | unix_dgram_disconnected(sk, old_peer); | 911 | unix_dgram_disconnected(sk, old_peer); |
912 | sock_put(old_peer); | 912 | sock_put(old_peer); |
913 | } else { | 913 | } else { |
914 | unix_peer(sk)=other; | 914 | unix_peer(sk)=other; |
915 | unix_state_wunlock(sk); | 915 | unix_state_unlock(sk); |
916 | } | 916 | } |
917 | return 0; | 917 | return 0; |
918 | 918 | ||
919 | out_unlock: | 919 | out_unlock: |
920 | unix_state_wunlock(sk); | 920 | unix_state_unlock(sk); |
921 | sock_put(other); | 921 | sock_put(other); |
922 | out: | 922 | out: |
923 | return err; | 923 | return err; |
@@ -936,7 +936,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo) | |||
936 | (skb_queue_len(&other->sk_receive_queue) > | 936 | (skb_queue_len(&other->sk_receive_queue) > |
937 | other->sk_max_ack_backlog); | 937 | other->sk_max_ack_backlog); |
938 | 938 | ||
939 | unix_state_runlock(other); | 939 | unix_state_unlock(other); |
940 | 940 | ||
941 | if (sched) | 941 | if (sched) |
942 | timeo = schedule_timeout(timeo); | 942 | timeo = schedule_timeout(timeo); |
@@ -994,11 +994,11 @@ restart: | |||
994 | goto out; | 994 | goto out; |
995 | 995 | ||
996 | /* Latch state of peer */ | 996 | /* Latch state of peer */ |
997 | unix_state_rlock(other); | 997 | unix_state_lock(other); |
998 | 998 | ||
999 | /* Apparently VFS overslept socket death. Retry. */ | 999 | /* Apparently VFS overslept socket death. Retry. */ |
1000 | if (sock_flag(other, SOCK_DEAD)) { | 1000 | if (sock_flag(other, SOCK_DEAD)) { |
1001 | unix_state_runlock(other); | 1001 | unix_state_unlock(other); |
1002 | sock_put(other); | 1002 | sock_put(other); |
1003 | goto restart; | 1003 | goto restart; |
1004 | } | 1004 | } |
@@ -1048,18 +1048,18 @@ restart: | |||
1048 | goto out_unlock; | 1048 | goto out_unlock; |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | unix_state_wlock_nested(sk); | 1051 | unix_state_lock_nested(sk); |
1052 | 1052 | ||
1053 | if (sk->sk_state != st) { | 1053 | if (sk->sk_state != st) { |
1054 | unix_state_wunlock(sk); | 1054 | unix_state_unlock(sk); |
1055 | unix_state_runlock(other); | 1055 | unix_state_unlock(other); |
1056 | sock_put(other); | 1056 | sock_put(other); |
1057 | goto restart; | 1057 | goto restart; |
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | err = security_unix_stream_connect(sock, other->sk_socket, newsk); | 1060 | err = security_unix_stream_connect(sock, other->sk_socket, newsk); |
1061 | if (err) { | 1061 | if (err) { |
1062 | unix_state_wunlock(sk); | 1062 | unix_state_unlock(sk); |
1063 | goto out_unlock; | 1063 | goto out_unlock; |
1064 | } | 1064 | } |
1065 | 1065 | ||
@@ -1096,7 +1096,7 @@ restart: | |||
1096 | smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */ | 1096 | smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */ |
1097 | unix_peer(sk) = newsk; | 1097 | unix_peer(sk) = newsk; |
1098 | 1098 | ||
1099 | unix_state_wunlock(sk); | 1099 | unix_state_unlock(sk); |
1100 | 1100 | ||
1101 | /* take ten and and send info to listening sock */ | 1101 | /* take ten and and send info to listening sock */ |
1102 | spin_lock(&other->sk_receive_queue.lock); | 1102 | spin_lock(&other->sk_receive_queue.lock); |
@@ -1105,14 +1105,14 @@ restart: | |||
1105 | * is installed to listening socket. */ | 1105 | * is installed to listening socket. */ |
1106 | atomic_inc(&newu->inflight); | 1106 | atomic_inc(&newu->inflight); |
1107 | spin_unlock(&other->sk_receive_queue.lock); | 1107 | spin_unlock(&other->sk_receive_queue.lock); |
1108 | unix_state_runlock(other); | 1108 | unix_state_unlock(other); |
1109 | other->sk_data_ready(other, 0); | 1109 | other->sk_data_ready(other, 0); |
1110 | sock_put(other); | 1110 | sock_put(other); |
1111 | return 0; | 1111 | return 0; |
1112 | 1112 | ||
1113 | out_unlock: | 1113 | out_unlock: |
1114 | if (other) | 1114 | if (other) |
1115 | unix_state_runlock(other); | 1115 | unix_state_unlock(other); |
1116 | 1116 | ||
1117 | out: | 1117 | out: |
1118 | if (skb) | 1118 | if (skb) |
@@ -1178,10 +1178,10 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags) | |||
1178 | wake_up_interruptible(&unix_sk(sk)->peer_wait); | 1178 | wake_up_interruptible(&unix_sk(sk)->peer_wait); |
1179 | 1179 | ||
1180 | /* attach accepted sock to socket */ | 1180 | /* attach accepted sock to socket */ |
1181 | unix_state_wlock(tsk); | 1181 | unix_state_lock(tsk); |
1182 | newsock->state = SS_CONNECTED; | 1182 | newsock->state = SS_CONNECTED; |
1183 | sock_graft(tsk, newsock); | 1183 | sock_graft(tsk, newsock); |
1184 | unix_state_wunlock(tsk); | 1184 | unix_state_unlock(tsk); |
1185 | return 0; | 1185 | return 0; |
1186 | 1186 | ||
1187 | out: | 1187 | out: |
@@ -1208,7 +1208,7 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_ | |||
1208 | } | 1208 | } |
1209 | 1209 | ||
1210 | u = unix_sk(sk); | 1210 | u = unix_sk(sk); |
1211 | unix_state_rlock(sk); | 1211 | unix_state_lock(sk); |
1212 | if (!u->addr) { | 1212 | if (!u->addr) { |
1213 | sunaddr->sun_family = AF_UNIX; | 1213 | sunaddr->sun_family = AF_UNIX; |
1214 | sunaddr->sun_path[0] = 0; | 1214 | sunaddr->sun_path[0] = 0; |
@@ -1219,7 +1219,7 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_ | |||
1219 | *uaddr_len = addr->len; | 1219 | *uaddr_len = addr->len; |
1220 | memcpy(sunaddr, addr->name, *uaddr_len); | 1220 | memcpy(sunaddr, addr->name, *uaddr_len); |
1221 | } | 1221 | } |
1222 | unix_state_runlock(sk); | 1222 | unix_state_unlock(sk); |
1223 | sock_put(sk); | 1223 | sock_put(sk); |
1224 | out: | 1224 | out: |
1225 | return err; | 1225 | return err; |
@@ -1337,7 +1337,7 @@ restart: | |||
1337 | goto out_free; | 1337 | goto out_free; |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | unix_state_rlock(other); | 1340 | unix_state_lock(other); |
1341 | err = -EPERM; | 1341 | err = -EPERM; |
1342 | if (!unix_may_send(sk, other)) | 1342 | if (!unix_may_send(sk, other)) |
1343 | goto out_unlock; | 1343 | goto out_unlock; |
@@ -1347,20 +1347,20 @@ restart: | |||
1347 | * Check with 1003.1g - what should | 1347 | * Check with 1003.1g - what should |
1348 | * datagram error | 1348 | * datagram error |
1349 | */ | 1349 | */ |
1350 | unix_state_runlock(other); | 1350 | unix_state_unlock(other); |
1351 | sock_put(other); | 1351 | sock_put(other); |
1352 | 1352 | ||
1353 | err = 0; | 1353 | err = 0; |
1354 | unix_state_wlock(sk); | 1354 | unix_state_lock(sk); |
1355 | if (unix_peer(sk) == other) { | 1355 | if (unix_peer(sk) == other) { |
1356 | unix_peer(sk)=NULL; | 1356 | unix_peer(sk)=NULL; |
1357 | unix_state_wunlock(sk); | 1357 | unix_state_unlock(sk); |
1358 | 1358 | ||
1359 | unix_dgram_disconnected(sk, other); | 1359 | unix_dgram_disconnected(sk, other); |
1360 | sock_put(other); | 1360 | sock_put(other); |
1361 | err = -ECONNREFUSED; | 1361 | err = -ECONNREFUSED; |
1362 | } else { | 1362 | } else { |
1363 | unix_state_wunlock(sk); | 1363 | unix_state_unlock(sk); |
1364 | } | 1364 | } |
1365 | 1365 | ||
1366 | other = NULL; | 1366 | other = NULL; |
@@ -1397,14 +1397,14 @@ restart: | |||
1397 | } | 1397 | } |
1398 | 1398 | ||
1399 | skb_queue_tail(&other->sk_receive_queue, skb); | 1399 | skb_queue_tail(&other->sk_receive_queue, skb); |
1400 | unix_state_runlock(other); | 1400 | unix_state_unlock(other); |
1401 | other->sk_data_ready(other, len); | 1401 | other->sk_data_ready(other, len); |
1402 | sock_put(other); | 1402 | sock_put(other); |
1403 | scm_destroy(siocb->scm); | 1403 | scm_destroy(siocb->scm); |
1404 | return len; | 1404 | return len; |
1405 | 1405 | ||
1406 | out_unlock: | 1406 | out_unlock: |
1407 | unix_state_runlock(other); | 1407 | unix_state_unlock(other); |
1408 | out_free: | 1408 | out_free: |
1409 | kfree_skb(skb); | 1409 | kfree_skb(skb); |
1410 | out: | 1410 | out: |
@@ -1494,14 +1494,14 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1494 | goto out_err; | 1494 | goto out_err; |
1495 | } | 1495 | } |
1496 | 1496 | ||
1497 | unix_state_rlock(other); | 1497 | unix_state_lock(other); |
1498 | 1498 | ||
1499 | if (sock_flag(other, SOCK_DEAD) || | 1499 | if (sock_flag(other, SOCK_DEAD) || |
1500 | (other->sk_shutdown & RCV_SHUTDOWN)) | 1500 | (other->sk_shutdown & RCV_SHUTDOWN)) |
1501 | goto pipe_err_free; | 1501 | goto pipe_err_free; |
1502 | 1502 | ||
1503 | skb_queue_tail(&other->sk_receive_queue, skb); | 1503 | skb_queue_tail(&other->sk_receive_queue, skb); |
1504 | unix_state_runlock(other); | 1504 | unix_state_unlock(other); |
1505 | other->sk_data_ready(other, size); | 1505 | other->sk_data_ready(other, size); |
1506 | sent+=size; | 1506 | sent+=size; |
1507 | } | 1507 | } |
@@ -1512,7 +1512,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1512 | return sent; | 1512 | return sent; |
1513 | 1513 | ||
1514 | pipe_err_free: | 1514 | pipe_err_free: |
1515 | unix_state_runlock(other); | 1515 | unix_state_unlock(other); |
1516 | kfree_skb(skb); | 1516 | kfree_skb(skb); |
1517 | pipe_err: | 1517 | pipe_err: |
1518 | if (sent==0 && !(msg->msg_flags&MSG_NOSIGNAL)) | 1518 | if (sent==0 && !(msg->msg_flags&MSG_NOSIGNAL)) |
@@ -1641,7 +1641,7 @@ static long unix_stream_data_wait(struct sock * sk, long timeo) | |||
1641 | { | 1641 | { |
1642 | DEFINE_WAIT(wait); | 1642 | DEFINE_WAIT(wait); |
1643 | 1643 | ||
1644 | unix_state_rlock(sk); | 1644 | unix_state_lock(sk); |
1645 | 1645 | ||
1646 | for (;;) { | 1646 | for (;;) { |
1647 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 1647 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); |
@@ -1654,14 +1654,14 @@ static long unix_stream_data_wait(struct sock * sk, long timeo) | |||
1654 | break; | 1654 | break; |
1655 | 1655 | ||
1656 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 1656 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
1657 | unix_state_runlock(sk); | 1657 | unix_state_unlock(sk); |
1658 | timeo = schedule_timeout(timeo); | 1658 | timeo = schedule_timeout(timeo); |
1659 | unix_state_rlock(sk); | 1659 | unix_state_lock(sk); |
1660 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | 1660 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); |
1661 | } | 1661 | } |
1662 | 1662 | ||
1663 | finish_wait(sk->sk_sleep, &wait); | 1663 | finish_wait(sk->sk_sleep, &wait); |
1664 | unix_state_runlock(sk); | 1664 | unix_state_unlock(sk); |
1665 | return timeo; | 1665 | return timeo; |
1666 | } | 1666 | } |
1667 | 1667 | ||
@@ -1816,12 +1816,12 @@ static int unix_shutdown(struct socket *sock, int mode) | |||
1816 | mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); | 1816 | mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); |
1817 | 1817 | ||
1818 | if (mode) { | 1818 | if (mode) { |
1819 | unix_state_wlock(sk); | 1819 | unix_state_lock(sk); |
1820 | sk->sk_shutdown |= mode; | 1820 | sk->sk_shutdown |= mode; |
1821 | other=unix_peer(sk); | 1821 | other=unix_peer(sk); |
1822 | if (other) | 1822 | if (other) |
1823 | sock_hold(other); | 1823 | sock_hold(other); |
1824 | unix_state_wunlock(sk); | 1824 | unix_state_unlock(sk); |
1825 | sk->sk_state_change(sk); | 1825 | sk->sk_state_change(sk); |
1826 | 1826 | ||
1827 | if (other && | 1827 | if (other && |
@@ -1833,9 +1833,9 @@ static int unix_shutdown(struct socket *sock, int mode) | |||
1833 | peer_mode |= SEND_SHUTDOWN; | 1833 | peer_mode |= SEND_SHUTDOWN; |
1834 | if (mode&SEND_SHUTDOWN) | 1834 | if (mode&SEND_SHUTDOWN) |
1835 | peer_mode |= RCV_SHUTDOWN; | 1835 | peer_mode |= RCV_SHUTDOWN; |
1836 | unix_state_wlock(other); | 1836 | unix_state_lock(other); |
1837 | other->sk_shutdown |= peer_mode; | 1837 | other->sk_shutdown |= peer_mode; |
1838 | unix_state_wunlock(other); | 1838 | unix_state_unlock(other); |
1839 | other->sk_state_change(other); | 1839 | other->sk_state_change(other); |
1840 | read_lock(&other->sk_callback_lock); | 1840 | read_lock(&other->sk_callback_lock); |
1841 | if (peer_mode == SHUTDOWN_MASK) | 1841 | if (peer_mode == SHUTDOWN_MASK) |
@@ -1973,7 +1973,7 @@ static int unix_seq_show(struct seq_file *seq, void *v) | |||
1973 | else { | 1973 | else { |
1974 | struct sock *s = v; | 1974 | struct sock *s = v; |
1975 | struct unix_sock *u = unix_sk(s); | 1975 | struct unix_sock *u = unix_sk(s); |
1976 | unix_state_rlock(s); | 1976 | unix_state_lock(s); |
1977 | 1977 | ||
1978 | seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu", | 1978 | seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu", |
1979 | s, | 1979 | s, |
@@ -2001,7 +2001,7 @@ static int unix_seq_show(struct seq_file *seq, void *v) | |||
2001 | for ( ; i < len; i++) | 2001 | for ( ; i < len; i++) |
2002 | seq_putc(seq, u->addr->name->sun_path[i]); | 2002 | seq_putc(seq, u->addr->name->sun_path[i]); |
2003 | } | 2003 | } |
2004 | unix_state_runlock(s); | 2004 | unix_state_unlock(s); |
2005 | seq_putc(seq, '\n'); | 2005 | seq_putc(seq, '\n'); |
2006 | } | 2006 | } |
2007 | 2007 | ||