diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2009-11-06 03:38:01 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-11-07 03:46:39 -0500 |
| commit | 58a9d73202dd40076992154e9acfb98489cc8eab (patch) | |
| tree | 9a070bac9b6eb007567acd6ece75d8fd9fb2fd7e /net/irda | |
| parent | 83927ba069a65326f39991a02d6a49ba3b7cea44 (diff) | |
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>
Diffstat (limited to 'net/irda')
| -rw-r--r-- | net/irda/af_irda.c | 331 |
1 files changed, 224 insertions, 107 deletions
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index e73a0016c0aa..10093aab6173 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
| @@ -714,11 +714,14 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, | |||
| 714 | struct sockaddr_irda saddr; | 714 | struct sockaddr_irda saddr; |
| 715 | struct sock *sk = sock->sk; | 715 | struct sock *sk = sock->sk; |
| 716 | struct irda_sock *self = irda_sk(sk); | 716 | struct irda_sock *self = irda_sk(sk); |
| 717 | int err; | ||
| 717 | 718 | ||
| 719 | lock_kernel(); | ||
| 718 | memset(&saddr, 0, sizeof(saddr)); | 720 | memset(&saddr, 0, sizeof(saddr)); |
| 719 | if (peer) { | 721 | if (peer) { |
| 722 | err = -ENOTCONN; | ||
| 720 | if (sk->sk_state != TCP_ESTABLISHED) | 723 | if (sk->sk_state != TCP_ESTABLISHED) |
| 721 | return -ENOTCONN; | 724 | goto out; |
| 722 | 725 | ||
| 723 | saddr.sir_family = AF_IRDA; | 726 | saddr.sir_family = AF_IRDA; |
| 724 | saddr.sir_lsap_sel = self->dtsap_sel; | 727 | saddr.sir_lsap_sel = self->dtsap_sel; |
| @@ -735,8 +738,10 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, | |||
| 735 | /* uaddr_len come to us uninitialised */ | 738 | /* uaddr_len come to us uninitialised */ |
| 736 | *uaddr_len = sizeof (struct sockaddr_irda); | 739 | *uaddr_len = sizeof (struct sockaddr_irda); |
| 737 | memcpy(uaddr, &saddr, *uaddr_len); | 740 | memcpy(uaddr, &saddr, *uaddr_len); |
| 738 | 741 | err = 0; | |
| 739 | return 0; | 742 | out: |
| 743 | unlock_kernel(); | ||
| 744 | return err; | ||
| 740 | } | 745 | } |
| 741 | 746 | ||
| 742 | /* | 747 | /* |
| @@ -748,21 +753,25 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, | |||
| 748 | static int irda_listen(struct socket *sock, int backlog) | 753 | static int irda_listen(struct socket *sock, int backlog) |
| 749 | { | 754 | { |
| 750 | struct sock *sk = sock->sk; | 755 | struct sock *sk = sock->sk; |
| 756 | int err = -EOPNOTSUPP; | ||
| 751 | 757 | ||
| 752 | IRDA_DEBUG(2, "%s()\n", __func__); | 758 | IRDA_DEBUG(2, "%s()\n", __func__); |
| 753 | 759 | ||
| 760 | lock_kernel(); | ||
| 754 | if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && | 761 | if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && |
| 755 | (sk->sk_type != SOCK_DGRAM)) | 762 | (sk->sk_type != SOCK_DGRAM)) |
| 756 | return -EOPNOTSUPP; | 763 | goto out; |
| 757 | 764 | ||
| 758 | if (sk->sk_state != TCP_LISTEN) { | 765 | if (sk->sk_state != TCP_LISTEN) { |
| 759 | sk->sk_max_ack_backlog = backlog; | 766 | sk->sk_max_ack_backlog = backlog; |
| 760 | sk->sk_state = TCP_LISTEN; | 767 | sk->sk_state = TCP_LISTEN; |
| 761 | 768 | ||
| 762 | return 0; | 769 | err = 0; |
| 763 | } | 770 | } |
| 771 | out: | ||
| 772 | unlock_kernel(); | ||
| 764 | 773 | ||
| 765 | return -EOPNOTSUPP; | 774 | return err; |
| 766 | } | 775 | } |
| 767 | 776 | ||
| 768 | /* | 777 | /* |
| @@ -783,36 +792,40 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
| 783 | if (addr_len != sizeof(struct sockaddr_irda)) | 792 | if (addr_len != sizeof(struct sockaddr_irda)) |
| 784 | return -EINVAL; | 793 | return -EINVAL; |
| 785 | 794 | ||
| 795 | lock_kernel(); | ||
| 786 | #ifdef CONFIG_IRDA_ULTRA | 796 | #ifdef CONFIG_IRDA_ULTRA |
| 787 | /* Special care for Ultra sockets */ | 797 | /* Special care for Ultra sockets */ |
| 788 | if ((sk->sk_type == SOCK_DGRAM) && | 798 | if ((sk->sk_type == SOCK_DGRAM) && |
| 789 | (sk->sk_protocol == IRDAPROTO_ULTRA)) { | 799 | (sk->sk_protocol == IRDAPROTO_ULTRA)) { |
| 790 | self->pid = addr->sir_lsap_sel; | 800 | self->pid = addr->sir_lsap_sel; |
| 801 | err = -EOPNOTSUPP; | ||
| 791 | if (self->pid & 0x80) { | 802 | if (self->pid & 0x80) { |
| 792 | IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__); | 803 | IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__); |
| 793 | return -EOPNOTSUPP; | 804 | goto out; |
| 794 | } | 805 | } |
| 795 | err = irda_open_lsap(self, self->pid); | 806 | err = irda_open_lsap(self, self->pid); |
| 796 | if (err < 0) | 807 | if (err < 0) |
| 797 | return err; | 808 | goto out; |
| 798 | 809 | ||
| 799 | /* Pretend we are connected */ | 810 | /* Pretend we are connected */ |
| 800 | sock->state = SS_CONNECTED; | 811 | sock->state = SS_CONNECTED; |
| 801 | sk->sk_state = TCP_ESTABLISHED; | 812 | sk->sk_state = TCP_ESTABLISHED; |
| 813 | err = 0; | ||
| 802 | 814 | ||
| 803 | return 0; | 815 | goto out; |
| 804 | } | 816 | } |
| 805 | #endif /* CONFIG_IRDA_ULTRA */ | 817 | #endif /* CONFIG_IRDA_ULTRA */ |
| 806 | 818 | ||
| 807 | self->ias_obj = irias_new_object(addr->sir_name, jiffies); | 819 | self->ias_obj = irias_new_object(addr->sir_name, jiffies); |
| 820 | err = -ENOMEM; | ||
| 808 | if (self->ias_obj == NULL) | 821 | if (self->ias_obj == NULL) |
| 809 | return -ENOMEM; | 822 | goto out; |
| 810 | 823 | ||
| 811 | err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); | 824 | err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); |
| 812 | if (err < 0) { | 825 | if (err < 0) { |
| 813 | kfree(self->ias_obj->name); | 826 | kfree(self->ias_obj->name); |
| 814 | kfree(self->ias_obj); | 827 | kfree(self->ias_obj); |
| 815 | return err; | 828 | goto out; |
| 816 | } | 829 | } |
| 817 | 830 | ||
| 818 | /* Register with LM-IAS */ | 831 | /* Register with LM-IAS */ |
| @@ -820,7 +833,10 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
| 820 | self->stsap_sel, IAS_KERNEL_ATTR); | 833 | self->stsap_sel, IAS_KERNEL_ATTR); |
| 821 | irias_insert_object(self->ias_obj); | 834 | irias_insert_object(self->ias_obj); |
| 822 | 835 | ||
| 823 | return 0; | 836 | err = 0; |
| 837 | out: | ||
| 838 | unlock_kernel(); | ||
| 839 | return err; | ||
| 824 | } | 840 | } |
| 825 | 841 | ||
| 826 | /* | 842 | /* |
| @@ -839,22 +855,26 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 839 | 855 | ||
| 840 | IRDA_DEBUG(2, "%s()\n", __func__); | 856 | IRDA_DEBUG(2, "%s()\n", __func__); |
| 841 | 857 | ||
| 858 | lock_kernel(); | ||
| 842 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); | 859 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); |
| 843 | if (err) | 860 | if (err) |
| 844 | return err; | 861 | goto out; |
| 845 | 862 | ||
| 863 | err = -EINVAL; | ||
| 846 | if (sock->state != SS_UNCONNECTED) | 864 | if (sock->state != SS_UNCONNECTED) |
| 847 | return -EINVAL; | 865 | goto out; |
| 848 | 866 | ||
| 849 | if ((sk = sock->sk) == NULL) | 867 | if ((sk = sock->sk) == NULL) |
| 850 | return -EINVAL; | 868 | goto out; |
| 851 | 869 | ||
| 870 | err = -EOPNOTSUPP; | ||
| 852 | if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && | 871 | if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && |
| 853 | (sk->sk_type != SOCK_DGRAM)) | 872 | (sk->sk_type != SOCK_DGRAM)) |
| 854 | return -EOPNOTSUPP; | 873 | goto out; |
| 855 | 874 | ||
| 875 | err = -EINVAL; | ||
| 856 | if (sk->sk_state != TCP_LISTEN) | 876 | if (sk->sk_state != TCP_LISTEN) |
| 857 | return -EINVAL; | 877 | goto out; |
| 858 | 878 | ||
| 859 | /* | 879 | /* |
| 860 | * The read queue this time is holding sockets ready to use | 880 | * 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) | |||
| 875 | break; | 895 | break; |
| 876 | 896 | ||
| 877 | /* Non blocking operation */ | 897 | /* Non blocking operation */ |
| 898 | err = -EWOULDBLOCK; | ||
| 878 | if (flags & O_NONBLOCK) | 899 | if (flags & O_NONBLOCK) |
| 879 | return -EWOULDBLOCK; | 900 | goto out; |
| 880 | 901 | ||
| 881 | err = wait_event_interruptible(*(sk->sk_sleep), | 902 | err = wait_event_interruptible(*(sk->sk_sleep), |
| 882 | skb_peek(&sk->sk_receive_queue)); | 903 | skb_peek(&sk->sk_receive_queue)); |
| 883 | if (err) | 904 | if (err) |
| 884 | return err; | 905 | goto out; |
| 885 | } | 906 | } |
| 886 | 907 | ||
| 887 | newsk = newsock->sk; | 908 | newsk = newsock->sk; |
| 909 | err = -EIO; | ||
| 888 | if (newsk == NULL) | 910 | if (newsk == NULL) |
| 889 | return -EIO; | 911 | goto out; |
| 890 | 912 | ||
| 891 | newsk->sk_state = TCP_ESTABLISHED; | 913 | newsk->sk_state = TCP_ESTABLISHED; |
| 892 | 914 | ||
| @@ -894,10 +916,11 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 894 | 916 | ||
| 895 | /* Now attach up the new socket */ | 917 | /* Now attach up the new socket */ |
| 896 | new->tsap = irttp_dup(self->tsap, new); | 918 | new->tsap = irttp_dup(self->tsap, new); |
| 919 | err = -EPERM; /* value does not seem to make sense. -arnd */ | ||
| 897 | if (!new->tsap) { | 920 | if (!new->tsap) { |
| 898 | IRDA_DEBUG(0, "%s(), dup failed!\n", __func__); | 921 | IRDA_DEBUG(0, "%s(), dup failed!\n", __func__); |
| 899 | kfree_skb(skb); | 922 | kfree_skb(skb); |
| 900 | return -1; | 923 | goto out; |
| 901 | } | 924 | } |
| 902 | 925 | ||
| 903 | new->stsap_sel = new->tsap->stsap_sel; | 926 | new->stsap_sel = new->tsap->stsap_sel; |
| @@ -921,8 +944,10 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
| 921 | newsock->state = SS_CONNECTED; | 944 | newsock->state = SS_CONNECTED; |
| 922 | 945 | ||
| 923 | irda_connect_response(new); | 946 | irda_connect_response(new); |
| 924 | 947 | err = 0; | |
| 925 | return 0; | 948 | out: |
| 949 | unlock_kernel(); | ||
| 950 | return err; | ||
| 926 | } | 951 | } |
| 927 | 952 | ||
| 928 | /* | 953 | /* |
| @@ -955,28 +980,34 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 955 | 980 | ||
| 956 | IRDA_DEBUG(2, "%s(%p)\n", __func__, self); | 981 | IRDA_DEBUG(2, "%s(%p)\n", __func__, self); |
| 957 | 982 | ||
| 983 | lock_kernel(); | ||
| 958 | /* Don't allow connect for Ultra sockets */ | 984 | /* Don't allow connect for Ultra sockets */ |
| 985 | err = -ESOCKTNOSUPPORT; | ||
| 959 | if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA)) | 986 | if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA)) |
| 960 | return -ESOCKTNOSUPPORT; | 987 | goto out; |
| 961 | 988 | ||
| 962 | if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { | 989 | if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { |
| 963 | sock->state = SS_CONNECTED; | 990 | sock->state = SS_CONNECTED; |
| 964 | return 0; /* Connect completed during a ERESTARTSYS event */ | 991 | err = 0; |
| 992 | goto out; /* Connect completed during a ERESTARTSYS event */ | ||
| 965 | } | 993 | } |
| 966 | 994 | ||
| 967 | if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) { | 995 | if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) { |
| 968 | sock->state = SS_UNCONNECTED; | 996 | sock->state = SS_UNCONNECTED; |
| 969 | return -ECONNREFUSED; | 997 | err = -ECONNREFUSED; |
| 998 | goto out; | ||
| 970 | } | 999 | } |
| 971 | 1000 | ||
| 1001 | err = -EISCONN; /* No reconnect on a seqpacket socket */ | ||
| 972 | if (sk->sk_state == TCP_ESTABLISHED) | 1002 | if (sk->sk_state == TCP_ESTABLISHED) |
| 973 | return -EISCONN; /* No reconnect on a seqpacket socket */ | 1003 | goto out; |
| 974 | 1004 | ||
| 975 | sk->sk_state = TCP_CLOSE; | 1005 | sk->sk_state = TCP_CLOSE; |
| 976 | sock->state = SS_UNCONNECTED; | 1006 | sock->state = SS_UNCONNECTED; |
| 977 | 1007 | ||
| 1008 | err = -EINVAL; | ||
| 978 | if (addr_len != sizeof(struct sockaddr_irda)) | 1009 | if (addr_len != sizeof(struct sockaddr_irda)) |
| 979 | return -EINVAL; | 1010 | goto out; |
| 980 | 1011 | ||
| 981 | /* Check if user supplied any destination device address */ | 1012 | /* Check if user supplied any destination device address */ |
| 982 | if ((!addr->sir_addr) || (addr->sir_addr == DEV_ADDR_ANY)) { | 1013 | if ((!addr->sir_addr) || (addr->sir_addr == DEV_ADDR_ANY)) { |
| @@ -984,7 +1015,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 984 | err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name); | 1015 | err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name); |
| 985 | if (err) { | 1016 | if (err) { |
| 986 | IRDA_DEBUG(0, "%s(), auto-connect failed!\n", __func__); | 1017 | IRDA_DEBUG(0, "%s(), auto-connect failed!\n", __func__); |
| 987 | return err; | 1018 | goto out; |
| 988 | } | 1019 | } |
| 989 | } else { | 1020 | } else { |
| 990 | /* Use the one provided by the user */ | 1021 | /* Use the one provided by the user */ |
| @@ -1000,7 +1031,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 1000 | err = irda_find_lsap_sel(self, addr->sir_name); | 1031 | err = irda_find_lsap_sel(self, addr->sir_name); |
| 1001 | if (err) { | 1032 | if (err) { |
| 1002 | IRDA_DEBUG(0, "%s(), connect failed!\n", __func__); | 1033 | IRDA_DEBUG(0, "%s(), connect failed!\n", __func__); |
| 1003 | return err; | 1034 | goto out; |
| 1004 | } | 1035 | } |
| 1005 | } else { | 1036 | } else { |
| 1006 | /* Directly connect to the remote LSAP | 1037 | /* Directly connect to the remote LSAP |
| @@ -1025,29 +1056,35 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 1025 | self->max_sdu_size_rx, NULL); | 1056 | self->max_sdu_size_rx, NULL); |
| 1026 | if (err) { | 1057 | if (err) { |
| 1027 | IRDA_DEBUG(0, "%s(), connect failed!\n", __func__); | 1058 | IRDA_DEBUG(0, "%s(), connect failed!\n", __func__); |
| 1028 | return err; | 1059 | goto out; |
| 1029 | } | 1060 | } |
| 1030 | 1061 | ||
| 1031 | /* Now the loop */ | 1062 | /* Now the loop */ |
| 1063 | err = -EINPROGRESS; | ||
| 1032 | if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) | 1064 | if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) |
| 1033 | return -EINPROGRESS; | 1065 | goto out; |
| 1034 | 1066 | ||
| 1067 | err = -ERESTARTSYS; | ||
| 1035 | if (wait_event_interruptible(*(sk->sk_sleep), | 1068 | if (wait_event_interruptible(*(sk->sk_sleep), |
| 1036 | (sk->sk_state != TCP_SYN_SENT))) | 1069 | (sk->sk_state != TCP_SYN_SENT))) |
| 1037 | return -ERESTARTSYS; | 1070 | goto out; |
| 1038 | 1071 | ||
| 1039 | if (sk->sk_state != TCP_ESTABLISHED) { | 1072 | if (sk->sk_state != TCP_ESTABLISHED) { |
| 1040 | sock->state = SS_UNCONNECTED; | 1073 | sock->state = SS_UNCONNECTED; |
| 1041 | err = sock_error(sk); | 1074 | err = sock_error(sk); |
| 1042 | return err? err : -ECONNRESET; | 1075 | if (!err) |
| 1076 | err = -ECONNRESET; | ||
| 1077 | goto out; | ||
| 1043 | } | 1078 | } |
| 1044 | 1079 | ||
| 1045 | sock->state = SS_CONNECTED; | 1080 | sock->state = SS_CONNECTED; |
| 1046 | 1081 | ||
| 1047 | /* At this point, IrLMP has assigned our source address */ | 1082 | /* At this point, IrLMP has assigned our source address */ |
| 1048 | self->saddr = irttp_get_saddr(self->tsap); | 1083 | self->saddr = irttp_get_saddr(self->tsap); |
| 1049 | 1084 | err = 0; | |
| 1050 | return 0; | 1085 | out: |
| 1086 | unlock_kernel(); | ||
| 1087 | return err; | ||
| 1051 | } | 1088 | } |
| 1052 | 1089 | ||
| 1053 | static struct proto irda_proto = { | 1090 | static struct proto irda_proto = { |
| @@ -1193,6 +1230,7 @@ static int irda_release(struct socket *sock) | |||
| 1193 | if (sk == NULL) | 1230 | if (sk == NULL) |
| 1194 | return 0; | 1231 | return 0; |
| 1195 | 1232 | ||
| 1233 | lock_kernel(); | ||
| 1196 | lock_sock(sk); | 1234 | lock_sock(sk); |
| 1197 | sk->sk_state = TCP_CLOSE; | 1235 | sk->sk_state = TCP_CLOSE; |
| 1198 | sk->sk_shutdown |= SEND_SHUTDOWN; | 1236 | sk->sk_shutdown |= SEND_SHUTDOWN; |
| @@ -1211,6 +1249,7 @@ static int irda_release(struct socket *sock) | |||
| 1211 | /* Destroy networking socket if we are the last reference on it, | 1249 | /* Destroy networking socket if we are the last reference on it, |
| 1212 | * i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */ | 1250 | * i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */ |
| 1213 | sock_put(sk); | 1251 | sock_put(sk); |
| 1252 | unlock_kernel(); | ||
| 1214 | 1253 | ||
| 1215 | /* Notes on socket locking and deallocation... - Jean II | 1254 | /* Notes on socket locking and deallocation... - Jean II |
| 1216 | * In theory we should put pairs of sock_hold() / sock_put() to | 1255 | * 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, | |||
| 1258 | 1297 | ||
| 1259 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); | 1298 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); |
| 1260 | 1299 | ||
| 1300 | lock_kernel(); | ||
| 1261 | /* Note : socket.c set MSG_EOR on SEQPACKET sockets */ | 1301 | /* Note : socket.c set MSG_EOR on SEQPACKET sockets */ |
| 1262 | if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT | | 1302 | if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT | |
| 1263 | MSG_NOSIGNAL)) | 1303 | MSG_NOSIGNAL)) { |
| 1264 | return -EINVAL; | 1304 | err = -EINVAL; |
| 1305 | goto out; | ||
| 1306 | } | ||
| 1265 | 1307 | ||
| 1266 | if (sk->sk_shutdown & SEND_SHUTDOWN) | 1308 | if (sk->sk_shutdown & SEND_SHUTDOWN) |
| 1267 | goto out_err; | 1309 | goto out_err; |
| 1268 | 1310 | ||
| 1269 | if (sk->sk_state != TCP_ESTABLISHED) | 1311 | if (sk->sk_state != TCP_ESTABLISHED) { |
| 1270 | return -ENOTCONN; | 1312 | err = -ENOTCONN; |
| 1313 | goto out; | ||
| 1314 | } | ||
| 1271 | 1315 | ||
| 1272 | self = irda_sk(sk); | 1316 | self = irda_sk(sk); |
| 1273 | 1317 | ||
| 1274 | /* Check if IrTTP is wants us to slow down */ | 1318 | /* Check if IrTTP is wants us to slow down */ |
| 1275 | 1319 | ||
| 1276 | if (wait_event_interruptible(*(sk->sk_sleep), | 1320 | if (wait_event_interruptible(*(sk->sk_sleep), |
| 1277 | (self->tx_flow != FLOW_STOP || sk->sk_state != TCP_ESTABLISHED))) | 1321 | (self->tx_flow != FLOW_STOP || sk->sk_state != TCP_ESTABLISHED))) { |
| 1278 | return -ERESTARTSYS; | 1322 | err = -ERESTARTSYS; |
| 1323 | goto out; | ||
| 1324 | } | ||
| 1279 | 1325 | ||
| 1280 | /* Check if we are still connected */ | 1326 | /* Check if we are still connected */ |
| 1281 | if (sk->sk_state != TCP_ESTABLISHED) | 1327 | if (sk->sk_state != TCP_ESTABLISHED) { |
| 1282 | return -ENOTCONN; | 1328 | err = -ENOTCONN; |
| 1329 | goto out; | ||
| 1330 | } | ||
| 1283 | 1331 | ||
| 1284 | /* Check that we don't send out too big frames */ | 1332 | /* Check that we don't send out too big frames */ |
| 1285 | if (len > self->max_data_size) { | 1333 | if (len > self->max_data_size) { |
| @@ -1311,11 +1359,16 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1311 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); | 1359 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); |
| 1312 | goto out_err; | 1360 | goto out_err; |
| 1313 | } | 1361 | } |
| 1362 | |||
| 1363 | unlock_kernel(); | ||
| 1314 | /* Tell client how much data we actually sent */ | 1364 | /* Tell client how much data we actually sent */ |
| 1315 | return len; | 1365 | return len; |
| 1316 | 1366 | ||
| 1317 | out_err: | 1367 | out_err: |
| 1318 | return sk_stream_error(sk, msg->msg_flags, err); | 1368 | err = sk_stream_error(sk, msg->msg_flags, err); |
| 1369 | out: | ||
| 1370 | unlock_kernel(); | ||
| 1371 | return err; | ||
| 1319 | 1372 | ||
| 1320 | } | 1373 | } |
| 1321 | 1374 | ||
| @@ -1336,13 +1389,14 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
| 1336 | 1389 | ||
| 1337 | IRDA_DEBUG(4, "%s()\n", __func__); | 1390 | IRDA_DEBUG(4, "%s()\n", __func__); |
| 1338 | 1391 | ||
| 1392 | lock_kernel(); | ||
| 1339 | if ((err = sock_error(sk)) < 0) | 1393 | if ((err = sock_error(sk)) < 0) |
| 1340 | return err; | 1394 | goto out; |
| 1341 | 1395 | ||
| 1342 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, | 1396 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
| 1343 | flags & MSG_DONTWAIT, &err); | 1397 | flags & MSG_DONTWAIT, &err); |
| 1344 | if (!skb) | 1398 | if (!skb) |
| 1345 | return err; | 1399 | goto out; |
| 1346 | 1400 | ||
| 1347 | skb_reset_transport_header(skb); | 1401 | skb_reset_transport_header(skb); |
| 1348 | copied = skb->len; | 1402 | copied = skb->len; |
| @@ -1370,8 +1424,12 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
| 1370 | irttp_flow_request(self->tsap, FLOW_START); | 1424 | irttp_flow_request(self->tsap, FLOW_START); |
| 1371 | } | 1425 | } |
| 1372 | } | 1426 | } |
| 1373 | 1427 | unlock_kernel(); | |
| 1374 | return copied; | 1428 | return copied; |
| 1429 | |||
| 1430 | out: | ||
| 1431 | unlock_kernel(); | ||
| 1432 | return err; | ||
| 1375 | } | 1433 | } |
| 1376 | 1434 | ||
| 1377 | /* | 1435 | /* |
| @@ -1389,15 +1447,19 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
| 1389 | 1447 | ||
| 1390 | IRDA_DEBUG(3, "%s()\n", __func__); | 1448 | IRDA_DEBUG(3, "%s()\n", __func__); |
| 1391 | 1449 | ||
| 1450 | lock_kernel(); | ||
| 1392 | if ((err = sock_error(sk)) < 0) | 1451 | if ((err = sock_error(sk)) < 0) |
| 1393 | return err; | 1452 | goto out; |
| 1394 | 1453 | ||
| 1454 | err = -EINVAL; | ||
| 1395 | if (sock->flags & __SO_ACCEPTCON) | 1455 | if (sock->flags & __SO_ACCEPTCON) |
| 1396 | return(-EINVAL); | 1456 | goto out; |
| 1397 | 1457 | ||
| 1458 | err =-EOPNOTSUPP; | ||
| 1398 | if (flags & MSG_OOB) | 1459 | if (flags & MSG_OOB) |
| 1399 | return -EOPNOTSUPP; | 1460 | goto out; |
| 1400 | 1461 | ||
| 1462 | err = 0; | ||
| 1401 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); | 1463 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); |
| 1402 | timeo = sock_rcvtimeo(sk, noblock); | 1464 | timeo = sock_rcvtimeo(sk, noblock); |
| 1403 | 1465 | ||
| @@ -1409,7 +1471,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
| 1409 | 1471 | ||
| 1410 | if (skb == NULL) { | 1472 | if (skb == NULL) { |
| 1411 | DEFINE_WAIT(wait); | 1473 | DEFINE_WAIT(wait); |
| 1412 | int ret = 0; | 1474 | err = 0; |
| 1413 | 1475 | ||
| 1414 | if (copied >= target) | 1476 | if (copied >= target) |
| 1415 | break; | 1477 | break; |
| @@ -1419,25 +1481,25 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
| 1419 | /* | 1481 | /* |
| 1420 | * POSIX 1003.1g mandates this order. | 1482 | * POSIX 1003.1g mandates this order. |
| 1421 | */ | 1483 | */ |
| 1422 | ret = sock_error(sk); | 1484 | err = sock_error(sk); |
| 1423 | if (ret) | 1485 | if (err) |
| 1424 | ; | 1486 | ; |
| 1425 | else if (sk->sk_shutdown & RCV_SHUTDOWN) | 1487 | else if (sk->sk_shutdown & RCV_SHUTDOWN) |
| 1426 | ; | 1488 | ; |
| 1427 | else if (noblock) | 1489 | else if (noblock) |
| 1428 | ret = -EAGAIN; | 1490 | err = -EAGAIN; |
| 1429 | else if (signal_pending(current)) | 1491 | else if (signal_pending(current)) |
| 1430 | ret = sock_intr_errno(timeo); | 1492 | err = sock_intr_errno(timeo); |
| 1431 | else if (sk->sk_state != TCP_ESTABLISHED) | 1493 | else if (sk->sk_state != TCP_ESTABLISHED) |
| 1432 | ret = -ENOTCONN; | 1494 | err = -ENOTCONN; |
| 1433 | else if (skb_peek(&sk->sk_receive_queue) == NULL) | 1495 | else if (skb_peek(&sk->sk_receive_queue) == NULL) |
| 1434 | /* Wait process until data arrives */ | 1496 | /* Wait process until data arrives */ |
| 1435 | schedule(); | 1497 | schedule(); |
| 1436 | 1498 | ||
| 1437 | finish_wait(sk->sk_sleep, &wait); | 1499 | finish_wait(sk->sk_sleep, &wait); |
| 1438 | 1500 | ||
| 1439 | if (ret) | 1501 | if (err) |
| 1440 | return ret; | 1502 | goto out; |
| 1441 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 1503 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
| 1442 | break; | 1504 | break; |
| 1443 | 1505 | ||
| @@ -1490,7 +1552,9 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
| 1490 | } | 1552 | } |
| 1491 | } | 1553 | } |
| 1492 | 1554 | ||
| 1493 | return copied; | 1555 | out: |
| 1556 | unlock_kernel(); | ||
| 1557 | return err ? : copied; | ||
| 1494 | } | 1558 | } |
| 1495 | 1559 | ||
| 1496 | /* | 1560 | /* |
| @@ -1508,18 +1572,23 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
| 1508 | struct sk_buff *skb; | 1572 | struct sk_buff *skb; |
| 1509 | int err; | 1573 | int err; |
| 1510 | 1574 | ||
| 1575 | lock_kernel(); | ||
| 1576 | |||
| 1511 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); | 1577 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); |
| 1512 | 1578 | ||
| 1579 | err = -EINVAL; | ||
| 1513 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) | 1580 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) |
| 1514 | return -EINVAL; | 1581 | goto out; |
| 1515 | 1582 | ||
| 1516 | if (sk->sk_shutdown & SEND_SHUTDOWN) { | 1583 | if (sk->sk_shutdown & SEND_SHUTDOWN) { |
| 1517 | send_sig(SIGPIPE, current, 0); | 1584 | send_sig(SIGPIPE, current, 0); |
| 1518 | return -EPIPE; | 1585 | err = -EPIPE; |
| 1586 | goto out; | ||
| 1519 | } | 1587 | } |
| 1520 | 1588 | ||
| 1589 | err = -ENOTCONN; | ||
| 1521 | if (sk->sk_state != TCP_ESTABLISHED) | 1590 | if (sk->sk_state != TCP_ESTABLISHED) |
| 1522 | return -ENOTCONN; | 1591 | goto out; |
| 1523 | 1592 | ||
| 1524 | self = irda_sk(sk); | 1593 | self = irda_sk(sk); |
| 1525 | 1594 | ||
| @@ -1536,8 +1605,9 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
| 1536 | 1605 | ||
| 1537 | skb = sock_alloc_send_skb(sk, len + self->max_header_size, | 1606 | skb = sock_alloc_send_skb(sk, len + self->max_header_size, |
| 1538 | msg->msg_flags & MSG_DONTWAIT, &err); | 1607 | msg->msg_flags & MSG_DONTWAIT, &err); |
| 1608 | err = -ENOBUFS; | ||
| 1539 | if (!skb) | 1609 | if (!skb) |
| 1540 | return -ENOBUFS; | 1610 | goto out; |
| 1541 | 1611 | ||
| 1542 | skb_reserve(skb, self->max_header_size); | 1612 | skb_reserve(skb, self->max_header_size); |
| 1543 | skb_reset_transport_header(skb); | 1613 | skb_reset_transport_header(skb); |
| @@ -1547,7 +1617,7 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
| 1547 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); | 1617 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); |
| 1548 | if (err) { | 1618 | if (err) { |
| 1549 | kfree_skb(skb); | 1619 | kfree_skb(skb); |
| 1550 | return err; | 1620 | goto out; |
| 1551 | } | 1621 | } |
| 1552 | 1622 | ||
| 1553 | /* | 1623 | /* |
| @@ -1557,9 +1627,13 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
| 1557 | err = irttp_udata_request(self->tsap, skb); | 1627 | err = irttp_udata_request(self->tsap, skb); |
| 1558 | if (err) { | 1628 | if (err) { |
| 1559 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); | 1629 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); |
| 1560 | return err; | 1630 | goto out; |
| 1561 | } | 1631 | } |
| 1632 | unlock_kernel(); | ||
| 1562 | return len; | 1633 | return len; |
| 1634 | out: | ||
| 1635 | unlock_kernel(); | ||
| 1636 | return err; | ||
| 1563 | } | 1637 | } |
| 1564 | 1638 | ||
| 1565 | /* | 1639 | /* |
| @@ -1581,12 +1655,15 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
| 1581 | 1655 | ||
| 1582 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); | 1656 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); |
| 1583 | 1657 | ||
| 1658 | lock_kernel(); | ||
| 1659 | err = -EINVAL; | ||
| 1584 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) | 1660 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) |
| 1585 | return -EINVAL; | 1661 | goto out; |
| 1586 | 1662 | ||
| 1663 | err = -EPIPE; | ||
| 1587 | if (sk->sk_shutdown & SEND_SHUTDOWN) { | 1664 | if (sk->sk_shutdown & SEND_SHUTDOWN) { |
| 1588 | send_sig(SIGPIPE, current, 0); | 1665 | send_sig(SIGPIPE, current, 0); |
| 1589 | return -EPIPE; | 1666 | goto out; |
| 1590 | } | 1667 | } |
| 1591 | 1668 | ||
| 1592 | self = irda_sk(sk); | 1669 | self = irda_sk(sk); |
| @@ -1594,16 +1671,18 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
| 1594 | /* Check if an address was specified with sendto. Jean II */ | 1671 | /* Check if an address was specified with sendto. Jean II */ |
| 1595 | if (msg->msg_name) { | 1672 | if (msg->msg_name) { |
| 1596 | struct sockaddr_irda *addr = (struct sockaddr_irda *) msg->msg_name; | 1673 | struct sockaddr_irda *addr = (struct sockaddr_irda *) msg->msg_name; |
| 1674 | err = -EINVAL; | ||
| 1597 | /* Check address, extract pid. Jean II */ | 1675 | /* Check address, extract pid. Jean II */ |
| 1598 | if (msg->msg_namelen < sizeof(*addr)) | 1676 | if (msg->msg_namelen < sizeof(*addr)) |
| 1599 | return -EINVAL; | 1677 | goto out; |
| 1600 | if (addr->sir_family != AF_IRDA) | 1678 | if (addr->sir_family != AF_IRDA) |
| 1601 | return -EINVAL; | 1679 | goto out; |
| 1602 | 1680 | ||
| 1603 | pid = addr->sir_lsap_sel; | 1681 | pid = addr->sir_lsap_sel; |
| 1604 | if (pid & 0x80) { | 1682 | if (pid & 0x80) { |
| 1605 | IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__); | 1683 | IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __func__); |
| 1606 | return -EOPNOTSUPP; | 1684 | err = -EOPNOTSUPP; |
| 1685 | goto out; | ||
| 1607 | } | 1686 | } |
| 1608 | } else { | 1687 | } else { |
| 1609 | /* Check that the socket is properly bound to an Ultra | 1688 | /* 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, | |||
| 1612 | (sk->sk_state != TCP_ESTABLISHED)) { | 1691 | (sk->sk_state != TCP_ESTABLISHED)) { |
| 1613 | IRDA_DEBUG(0, "%s(), socket not bound to Ultra PID.\n", | 1692 | IRDA_DEBUG(0, "%s(), socket not bound to Ultra PID.\n", |
| 1614 | __func__); | 1693 | __func__); |
| 1615 | return -ENOTCONN; | 1694 | err = -ENOTCONN; |
| 1695 | goto out; | ||
| 1616 | } | 1696 | } |
| 1617 | /* Use PID from socket */ | 1697 | /* Use PID from socket */ |
| 1618 | bound = 1; | 1698 | bound = 1; |
| @@ -1631,8 +1711,9 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
| 1631 | 1711 | ||
| 1632 | skb = sock_alloc_send_skb(sk, len + self->max_header_size, | 1712 | skb = sock_alloc_send_skb(sk, len + self->max_header_size, |
| 1633 | msg->msg_flags & MSG_DONTWAIT, &err); | 1713 | msg->msg_flags & MSG_DONTWAIT, &err); |
| 1714 | err = -ENOBUFS; | ||
| 1634 | if (!skb) | 1715 | if (!skb) |
| 1635 | return -ENOBUFS; | 1716 | goto out; |
| 1636 | 1717 | ||
| 1637 | skb_reserve(skb, self->max_header_size); | 1718 | skb_reserve(skb, self->max_header_size); |
| 1638 | skb_reset_transport_header(skb); | 1719 | skb_reset_transport_header(skb); |
| @@ -1642,16 +1723,16 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
| 1642 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); | 1723 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); |
| 1643 | if (err) { | 1724 | if (err) { |
| 1644 | kfree_skb(skb); | 1725 | kfree_skb(skb); |
| 1645 | return err; | 1726 | goto out; |
| 1646 | } | 1727 | } |
| 1647 | 1728 | ||
| 1648 | err = irlmp_connless_data_request((bound ? self->lsap : NULL), | 1729 | err = irlmp_connless_data_request((bound ? self->lsap : NULL), |
| 1649 | skb, pid); | 1730 | skb, pid); |
| 1650 | if (err) { | 1731 | if (err) |
| 1651 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); | 1732 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); |
| 1652 | return err; | 1733 | out: |
| 1653 | } | 1734 | unlock_kernel(); |
| 1654 | return len; | 1735 | return err ? : len; |
| 1655 | } | 1736 | } |
| 1656 | #endif /* CONFIG_IRDA_ULTRA */ | 1737 | #endif /* CONFIG_IRDA_ULTRA */ |
| 1657 | 1738 | ||
| @@ -1665,6 +1746,8 @@ static int irda_shutdown(struct socket *sock, int how) | |||
| 1665 | 1746 | ||
| 1666 | IRDA_DEBUG(1, "%s(%p)\n", __func__, self); | 1747 | IRDA_DEBUG(1, "%s(%p)\n", __func__, self); |
| 1667 | 1748 | ||
| 1749 | lock_kernel(); | ||
| 1750 | |||
| 1668 | sk->sk_state = TCP_CLOSE; | 1751 | sk->sk_state = TCP_CLOSE; |
| 1669 | sk->sk_shutdown |= SEND_SHUTDOWN; | 1752 | sk->sk_shutdown |= SEND_SHUTDOWN; |
| 1670 | sk->sk_state_change(sk); | 1753 | sk->sk_state_change(sk); |
| @@ -1685,6 +1768,8 @@ static int irda_shutdown(struct socket *sock, int how) | |||
| 1685 | self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */ | 1768 | self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */ |
| 1686 | self->saddr = 0x0; /* so IrLMP assign us any link */ | 1769 | self->saddr = 0x0; /* so IrLMP assign us any link */ |
| 1687 | 1770 | ||
| 1771 | unlock_kernel(); | ||
| 1772 | |||
| 1688 | return 0; | 1773 | return 0; |
| 1689 | } | 1774 | } |
| 1690 | 1775 | ||
| @@ -1700,6 +1785,7 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, | |||
| 1700 | 1785 | ||
| 1701 | IRDA_DEBUG(4, "%s()\n", __func__); | 1786 | IRDA_DEBUG(4, "%s()\n", __func__); |
| 1702 | 1787 | ||
| 1788 | lock_kernel(); | ||
| 1703 | poll_wait(file, sk->sk_sleep, wait); | 1789 | poll_wait(file, sk->sk_sleep, wait); |
| 1704 | mask = 0; | 1790 | mask = 0; |
| 1705 | 1791 | ||
| @@ -1747,18 +1833,34 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, | |||
| 1747 | default: | 1833 | default: |
| 1748 | break; | 1834 | break; |
| 1749 | } | 1835 | } |
| 1836 | unlock_kernel(); | ||
| 1750 | return mask; | 1837 | return mask; |
| 1751 | } | 1838 | } |
| 1752 | 1839 | ||
| 1840 | static unsigned int irda_datagram_poll(struct file *file, struct socket *sock, | ||
| 1841 | poll_table *wait) | ||
| 1842 | { | ||
| 1843 | int err; | ||
| 1844 | |||
| 1845 | lock_kernel(); | ||
| 1846 | err = datagram_poll(file, sock, wait); | ||
| 1847 | unlock_kernel(); | ||
| 1848 | |||
| 1849 | return err; | ||
| 1850 | } | ||
| 1851 | |||
| 1753 | /* | 1852 | /* |
| 1754 | * Function irda_ioctl (sock, cmd, arg) | 1853 | * Function irda_ioctl (sock, cmd, arg) |
| 1755 | */ | 1854 | */ |
| 1756 | static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 1855 | static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
| 1757 | { | 1856 | { |
| 1758 | struct sock *sk = sock->sk; | 1857 | struct sock *sk = sock->sk; |
| 1858 | int err; | ||
| 1759 | 1859 | ||
| 1760 | IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd); | 1860 | IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd); |
| 1761 | 1861 | ||
| 1862 | lock_kernel(); | ||
| 1863 | err = -EINVAL; | ||
| 1762 | switch (cmd) { | 1864 | switch (cmd) { |
| 1763 | case TIOCOUTQ: { | 1865 | case TIOCOUTQ: { |
| 1764 | long amount; | 1866 | long amount; |
| @@ -1766,9 +1868,8 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
| 1766 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | 1868 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
| 1767 | if (amount < 0) | 1869 | if (amount < 0) |
| 1768 | amount = 0; | 1870 | amount = 0; |
| 1769 | if (put_user(amount, (unsigned int __user *)arg)) | 1871 | err = put_user(amount, (unsigned int __user *)arg); |
| 1770 | return -EFAULT; | 1872 | break; |
| 1771 | return 0; | ||
| 1772 | } | 1873 | } |
| 1773 | 1874 | ||
| 1774 | case TIOCINQ: { | 1875 | case TIOCINQ: { |
| @@ -1777,15 +1878,14 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
| 1777 | /* These two are safe on a single CPU system as only user tasks fiddle here */ | 1878 | /* These two are safe on a single CPU system as only user tasks fiddle here */ |
| 1778 | if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) | 1879 | if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) |
| 1779 | amount = skb->len; | 1880 | amount = skb->len; |
| 1780 | if (put_user(amount, (unsigned int __user *)arg)) | 1881 | err = put_user(amount, (unsigned int __user *)arg); |
| 1781 | return -EFAULT; | 1882 | break; |
| 1782 | return 0; | ||
| 1783 | } | 1883 | } |
| 1784 | 1884 | ||
| 1785 | case SIOCGSTAMP: | 1885 | case SIOCGSTAMP: |
| 1786 | if (sk != NULL) | 1886 | if (sk != NULL) |
| 1787 | return sock_get_timestamp(sk, (struct timeval __user *)arg); | 1887 | err = sock_get_timestamp(sk, (struct timeval __user *)arg); |
| 1788 | return -EINVAL; | 1888 | break; |
| 1789 | 1889 | ||
| 1790 | case SIOCGIFADDR: | 1890 | case SIOCGIFADDR: |
| 1791 | case SIOCSIFADDR: | 1891 | case SIOCSIFADDR: |
| @@ -1797,14 +1897,14 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
| 1797 | case SIOCSIFNETMASK: | 1897 | case SIOCSIFNETMASK: |
| 1798 | case SIOCGIFMETRIC: | 1898 | case SIOCGIFMETRIC: |
| 1799 | case SIOCSIFMETRIC: | 1899 | case SIOCSIFMETRIC: |
| 1800 | return -EINVAL; | 1900 | break; |
| 1801 | default: | 1901 | default: |
| 1802 | IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__); | 1902 | IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__); |
| 1803 | return -ENOIOCTLCMD; | 1903 | err = -ENOIOCTLCMD; |
| 1804 | } | 1904 | } |
| 1905 | unlock_kernel(); | ||
| 1805 | 1906 | ||
| 1806 | /*NOTREACHED*/ | 1907 | return err; |
| 1807 | return 0; | ||
| 1808 | } | 1908 | } |
| 1809 | 1909 | ||
| 1810 | #ifdef CONFIG_COMPAT | 1910 | #ifdef CONFIG_COMPAT |
| @@ -1826,7 +1926,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon | |||
| 1826 | * Set some options for the socket | 1926 | * Set some options for the socket |
| 1827 | * | 1927 | * |
| 1828 | */ | 1928 | */ |
| 1829 | static int irda_setsockopt(struct socket *sock, int level, int optname, | 1929 | static int __irda_setsockopt(struct socket *sock, int level, int optname, |
| 1830 | char __user *optval, unsigned int optlen) | 1930 | char __user *optval, unsigned int optlen) |
| 1831 | { | 1931 | { |
| 1832 | struct sock *sk = sock->sk; | 1932 | struct sock *sk = sock->sk; |
| @@ -2084,6 +2184,18 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, | |||
| 2084 | return 0; | 2184 | return 0; |
| 2085 | } | 2185 | } |
| 2086 | 2186 | ||
| 2187 | static int irda_setsockopt(struct socket *sock, int level, int optname, | ||
| 2188 | char __user *optval, unsigned int optlen) | ||
| 2189 | { | ||
| 2190 | int err; | ||
| 2191 | |||
| 2192 | lock_kernel(); | ||
| 2193 | err = __irda_setsockopt(sock, level, optname, optval, optlen); | ||
| 2194 | unlock_kernel(); | ||
| 2195 | |||
| 2196 | return err; | ||
| 2197 | } | ||
| 2198 | |||
| 2087 | /* | 2199 | /* |
| 2088 | * Function irda_extract_ias_value(ias_opt, ias_value) | 2200 | * Function irda_extract_ias_value(ias_opt, ias_value) |
| 2089 | * | 2201 | * |
| @@ -2136,7 +2248,7 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt, | |||
| 2136 | /* | 2248 | /* |
| 2137 | * Function irda_getsockopt (sock, level, optname, optval, optlen) | 2249 | * Function irda_getsockopt (sock, level, optname, optval, optlen) |
| 2138 | */ | 2250 | */ |
| 2139 | static int irda_getsockopt(struct socket *sock, int level, int optname, | 2251 | static int __irda_getsockopt(struct socket *sock, int level, int optname, |
| 2140 | char __user *optval, int __user *optlen) | 2252 | char __user *optval, int __user *optlen) |
| 2141 | { | 2253 | { |
| 2142 | struct sock *sk = sock->sk; | 2254 | struct sock *sk = sock->sk; |
| @@ -2464,13 +2576,25 @@ bed: | |||
| 2464 | return 0; | 2576 | return 0; |
| 2465 | } | 2577 | } |
| 2466 | 2578 | ||
| 2579 | static int irda_getsockopt(struct socket *sock, int level, int optname, | ||
| 2580 | char __user *optval, int __user *optlen) | ||
| 2581 | { | ||
| 2582 | int err; | ||
| 2583 | |||
| 2584 | lock_kernel(); | ||
| 2585 | err = __irda_getsockopt(sock, level, optname, optval, optlen); | ||
| 2586 | unlock_kernel(); | ||
| 2587 | |||
| 2588 | return err; | ||
| 2589 | } | ||
| 2590 | |||
| 2467 | static const struct net_proto_family irda_family_ops = { | 2591 | static const struct net_proto_family irda_family_ops = { |
| 2468 | .family = PF_IRDA, | 2592 | .family = PF_IRDA, |
| 2469 | .create = irda_create, | 2593 | .create = irda_create, |
| 2470 | .owner = THIS_MODULE, | 2594 | .owner = THIS_MODULE, |
| 2471 | }; | 2595 | }; |
| 2472 | 2596 | ||
| 2473 | static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = { | 2597 | static const struct proto_ops irda_stream_ops = { |
| 2474 | .family = PF_IRDA, | 2598 | .family = PF_IRDA, |
| 2475 | .owner = THIS_MODULE, | 2599 | .owner = THIS_MODULE, |
| 2476 | .release = irda_release, | 2600 | .release = irda_release, |
| @@ -2494,7 +2618,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = { | |||
| 2494 | .sendpage = sock_no_sendpage, | 2618 | .sendpage = sock_no_sendpage, |
| 2495 | }; | 2619 | }; |
| 2496 | 2620 | ||
| 2497 | static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = { | 2621 | static const struct proto_ops irda_seqpacket_ops = { |
| 2498 | .family = PF_IRDA, | 2622 | .family = PF_IRDA, |
| 2499 | .owner = THIS_MODULE, | 2623 | .owner = THIS_MODULE, |
| 2500 | .release = irda_release, | 2624 | .release = irda_release, |
| @@ -2503,7 +2627,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = { | |||
| 2503 | .socketpair = sock_no_socketpair, | 2627 | .socketpair = sock_no_socketpair, |
| 2504 | .accept = irda_accept, | 2628 | .accept = irda_accept, |
| 2505 | .getname = irda_getname, | 2629 | .getname = irda_getname, |
| 2506 | .poll = datagram_poll, | 2630 | .poll = irda_datagram_poll, |
| 2507 | .ioctl = irda_ioctl, | 2631 | .ioctl = irda_ioctl, |
| 2508 | #ifdef CONFIG_COMPAT | 2632 | #ifdef CONFIG_COMPAT |
| 2509 | .compat_ioctl = irda_compat_ioctl, | 2633 | .compat_ioctl = irda_compat_ioctl, |
| @@ -2518,7 +2642,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = { | |||
| 2518 | .sendpage = sock_no_sendpage, | 2642 | .sendpage = sock_no_sendpage, |
| 2519 | }; | 2643 | }; |
| 2520 | 2644 | ||
| 2521 | static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = { | 2645 | static const struct proto_ops irda_dgram_ops = { |
| 2522 | .family = PF_IRDA, | 2646 | .family = PF_IRDA, |
| 2523 | .owner = THIS_MODULE, | 2647 | .owner = THIS_MODULE, |
| 2524 | .release = irda_release, | 2648 | .release = irda_release, |
| @@ -2527,7 +2651,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = { | |||
| 2527 | .socketpair = sock_no_socketpair, | 2651 | .socketpair = sock_no_socketpair, |
| 2528 | .accept = irda_accept, | 2652 | .accept = irda_accept, |
| 2529 | .getname = irda_getname, | 2653 | .getname = irda_getname, |
| 2530 | .poll = datagram_poll, | 2654 | .poll = irda_datagram_poll, |
| 2531 | .ioctl = irda_ioctl, | 2655 | .ioctl = irda_ioctl, |
| 2532 | #ifdef CONFIG_COMPAT | 2656 | #ifdef CONFIG_COMPAT |
| 2533 | .compat_ioctl = irda_compat_ioctl, | 2657 | .compat_ioctl = irda_compat_ioctl, |
| @@ -2543,7 +2667,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = { | |||
| 2543 | }; | 2667 | }; |
| 2544 | 2668 | ||
| 2545 | #ifdef CONFIG_IRDA_ULTRA | 2669 | #ifdef CONFIG_IRDA_ULTRA |
| 2546 | static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = { | 2670 | static const struct proto_ops irda_ultra_ops = { |
| 2547 | .family = PF_IRDA, | 2671 | .family = PF_IRDA, |
| 2548 | .owner = THIS_MODULE, | 2672 | .owner = THIS_MODULE, |
| 2549 | .release = irda_release, | 2673 | .release = irda_release, |
| @@ -2552,7 +2676,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = { | |||
| 2552 | .socketpair = sock_no_socketpair, | 2676 | .socketpair = sock_no_socketpair, |
| 2553 | .accept = sock_no_accept, | 2677 | .accept = sock_no_accept, |
| 2554 | .getname = irda_getname, | 2678 | .getname = irda_getname, |
| 2555 | .poll = datagram_poll, | 2679 | .poll = irda_datagram_poll, |
| 2556 | .ioctl = irda_ioctl, | 2680 | .ioctl = irda_ioctl, |
| 2557 | #ifdef CONFIG_COMPAT | 2681 | #ifdef CONFIG_COMPAT |
| 2558 | .compat_ioctl = irda_compat_ioctl, | 2682 | .compat_ioctl = irda_compat_ioctl, |
| @@ -2568,13 +2692,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = { | |||
| 2568 | }; | 2692 | }; |
| 2569 | #endif /* CONFIG_IRDA_ULTRA */ | 2693 | #endif /* CONFIG_IRDA_ULTRA */ |
| 2570 | 2694 | ||
| 2571 | SOCKOPS_WRAP(irda_stream, PF_IRDA); | ||
| 2572 | SOCKOPS_WRAP(irda_seqpacket, PF_IRDA); | ||
| 2573 | SOCKOPS_WRAP(irda_dgram, PF_IRDA); | ||
| 2574 | #ifdef CONFIG_IRDA_ULTRA | ||
| 2575 | SOCKOPS_WRAP(irda_ultra, PF_IRDA); | ||
| 2576 | #endif /* CONFIG_IRDA_ULTRA */ | ||
| 2577 | |||
| 2578 | /* | 2695 | /* |
| 2579 | * Function irsock_init (pro) | 2696 | * Function irsock_init (pro) |
| 2580 | * | 2697 | * |
