~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/core/stream.c

Version: ~ [ linux-5.6-rc3 ] ~ [ linux-5.5.6 ] ~ [ linux-5.4.22 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.106 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.171 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.214 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.214 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.82 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *     SUCS NET3:
  3  *
  4  *     Generic stream handling routines. These are generic for most
  5  *     protocols. Even IP. Tonight 8-).
  6  *     This is used because TCP, LLC (others too) layer all have mostly
  7  *     identical sendmsg() and recvmsg() code.
  8  *     So we (will) share it here.
  9  *
 10  *     Authors:        Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 11  *                     (from old tcp.c code)
 12  *                     Alan Cox <alan@lxorguk.ukuu.org.uk> (Borrowed comments 8-))
 13  */
 14 
 15 #include <linux/module.h>
 16 #include <linux/net.h>
 17 #include <linux/signal.h>
 18 #include <linux/tcp.h>
 19 #include <linux/wait.h>
 20 #include <net/sock.h>
 21 
 22 /**
 23  * sk_stream_write_space - stream socket write_space callback.
 24  * @sk: socket
 25  *
 26  * FIXME: write proper description
 27  */
 28 void sk_stream_write_space(struct sock *sk)
 29 {
 30         struct socket *sock = sk->sk_socket;
 31         struct socket_wq *wq;
 32 
 33         if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk) && sock) {
 34                 clear_bit(SOCK_NOSPACE, &sock->flags);
 35 
 36                 rcu_read_lock();
 37                 wq = rcu_dereference(sk->sk_wq);
 38                 if (wq_has_sleeper(wq))
 39                         wake_up_interruptible_poll(&wq->wait, POLLOUT |
 40                                                 POLLWRNORM | POLLWRBAND);
 41                 if (wq && wq->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
 42                         sock_wake_async(sock, SOCK_WAKE_SPACE, POLL_OUT);
 43                 rcu_read_unlock();
 44         }
 45 }
 46 EXPORT_SYMBOL(sk_stream_write_space);
 47 
 48 /**
 49  * sk_stream_wait_connect - Wait for a socket to get into the connected state
 50  * @sk: sock to wait on
 51  * @timeo_p: for how long to wait
 52  *
 53  * Must be called with the socket locked.
 54  */
 55 int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
 56 {
 57         struct task_struct *tsk = current;
 58         DEFINE_WAIT(wait);
 59         int done;
 60 
 61         do {
 62                 int err = sock_error(sk);
 63                 if (err)
 64                         return err;
 65                 if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
 66                         return -EPIPE;
 67                 if (!*timeo_p)
 68                         return -EAGAIN;
 69                 if (signal_pending(tsk))
 70                         return sock_intr_errno(*timeo_p);
 71 
 72                 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 73                 sk->sk_write_pending++;
 74                 done = sk_wait_event(sk, timeo_p,
 75                                      !sk->sk_err &&
 76                                      !((1 << sk->sk_state) &
 77                                        ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
 78                 finish_wait(sk_sleep(sk), &wait);
 79                 sk->sk_write_pending--;
 80         } while (!done);
 81         return 0;
 82 }
 83 EXPORT_SYMBOL(sk_stream_wait_connect);
 84 
 85 /**
 86  * sk_stream_closing - Return 1 if we still have things to send in our buffers.
 87  * @sk: socket to verify
 88  */
 89 static inline int sk_stream_closing(struct sock *sk)
 90 {
 91         return (1 << sk->sk_state) &
 92                (TCPF_FIN_WAIT1 | TCPF_CLOSING | TCPF_LAST_ACK);
 93 }
 94 
 95 void sk_stream_wait_close(struct sock *sk, long timeout)
 96 {
 97         if (timeout) {
 98                 DEFINE_WAIT(wait);
 99 
100                 do {
101                         prepare_to_wait(sk_sleep(sk), &wait,
102                                         TASK_INTERRUPTIBLE);
103                         if (sk_wait_event(sk, &timeout, !sk_stream_closing(sk)))
104                                 break;
105                 } while (!signal_pending(current) && timeout);
106 
107                 finish_wait(sk_sleep(sk), &wait);
108         }
109 }
110 EXPORT_SYMBOL(sk_stream_wait_close);
111 
112 /**
113  * sk_stream_wait_memory - Wait for more memory for a socket
114  * @sk: socket to wait for memory
115  * @timeo_p: for how long
116  */
117 int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
118 {
119         int err = 0;
120         long vm_wait = 0;
121         long current_timeo = *timeo_p;
122         DEFINE_WAIT(wait);
123 
124         if (sk_stream_memory_free(sk))
125                 current_timeo = vm_wait = (net_random() % (HZ / 5)) + 2;
126 
127         while (1) {
128                 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
129 
130                 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
131 
132                 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
133                         goto do_error;
134                 if (!*timeo_p)
135                         goto do_nonblock;
136                 if (signal_pending(current))
137                         goto do_interrupted;
138                 clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
139                 if (sk_stream_memory_free(sk) && !vm_wait)
140                         break;
141 
142                 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
143                 sk->sk_write_pending++;
144                 sk_wait_event(sk, &current_timeo, sk->sk_err ||
145                                                   (sk->sk_shutdown & SEND_SHUTDOWN) ||
146                                                   (sk_stream_memory_free(sk) &&
147                                                   !vm_wait));
148                 sk->sk_write_pending--;
149 
150                 if (vm_wait) {
151                         vm_wait -= current_timeo;
152                         current_timeo = *timeo_p;
153                         if (current_timeo != MAX_SCHEDULE_TIMEOUT &&
154                             (current_timeo -= vm_wait) < 0)
155                                 current_timeo = 0;
156                         vm_wait = 0;
157                 }
158                 *timeo_p = current_timeo;
159         }
160 out:
161         finish_wait(sk_sleep(sk), &wait);
162         return err;
163 
164 do_error:
165         err = -EPIPE;
166         goto out;
167 do_nonblock:
168         err = -EAGAIN;
169         goto out;
170 do_interrupted:
171         err = sock_intr_errno(*timeo_p);
172         goto out;
173 }
174 EXPORT_SYMBOL(sk_stream_wait_memory);
175 
176 int sk_stream_error(struct sock *sk, int flags, int err)
177 {
178         if (err == -EPIPE)
179                 err = sock_error(sk) ? : -EPIPE;
180         if (err == -EPIPE && !(flags & MSG_NOSIGNAL))
181                 send_sig(SIGPIPE, current, 0);
182         return err;
183 }
184 EXPORT_SYMBOL(sk_stream_error);
185 
186 void sk_stream_kill_queues(struct sock *sk)
187 {
188         /* First the read buffer. */
189         __skb_queue_purge(&sk->sk_receive_queue);
190 
191         /* Next, the error queue. */
192         __skb_queue_purge(&sk->sk_error_queue);
193 
194         /* Next, the write queue. */
195         WARN_ON(!skb_queue_empty(&sk->sk_write_queue));
196 
197         /* Account for returned memory. */
198         sk_mem_reclaim(sk);
199 
200         WARN_ON(sk->sk_wmem_queued);
201         WARN_ON(sk->sk_forward_alloc);
202 
203         /* It is _impossible_ for the backlog to contain anything
204          * when we get here.  All user references to this socket
205          * have gone away, only the net layer knows can touch it.
206          */
207 }
208 EXPORT_SYMBOL(sk_stream_kill_queues);
209 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp