diff options
Diffstat (limited to 'net/rxrpc/ar-output.c')
-rw-r--r-- | net/rxrpc/ar-output.c | 84 |
1 files changed, 80 insertions, 4 deletions
diff --git a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c index 67aa9510f09b..5cdde4a48ed1 100644 --- a/net/rxrpc/ar-output.c +++ b/net/rxrpc/ar-output.c | |||
@@ -113,7 +113,7 @@ static void rxrpc_send_abort(struct rxrpc_call *call, u32 abort_code) | |||
113 | clear_bit(RXRPC_CALL_RESEND_TIMER, &call->events); | 113 | clear_bit(RXRPC_CALL_RESEND_TIMER, &call->events); |
114 | clear_bit(RXRPC_CALL_ACK, &call->events); | 114 | clear_bit(RXRPC_CALL_ACK, &call->events); |
115 | clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags); | 115 | clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags); |
116 | schedule_work(&call->processor); | 116 | rxrpc_queue_call(call); |
117 | } | 117 | } |
118 | 118 | ||
119 | write_unlock_bh(&call->state_lock); | 119 | write_unlock_bh(&call->state_lock); |
@@ -194,6 +194,77 @@ int rxrpc_client_sendmsg(struct kiocb *iocb, struct rxrpc_sock *rx, | |||
194 | return ret; | 194 | return ret; |
195 | } | 195 | } |
196 | 196 | ||
197 | /** | ||
198 | * rxrpc_kernel_send_data - Allow a kernel service to send data on a call | ||
199 | * @call: The call to send data through | ||
200 | * @msg: The data to send | ||
201 | * @len: The amount of data to send | ||
202 | * | ||
203 | * Allow a kernel service to send data on a call. The call must be in an state | ||
204 | * appropriate to sending data. No control data should be supplied in @msg, | ||
205 | * nor should an address be supplied. MSG_MORE should be flagged if there's | ||
206 | * more data to come, otherwise this data will end the transmission phase. | ||
207 | */ | ||
208 | int rxrpc_kernel_send_data(struct rxrpc_call *call, struct msghdr *msg, | ||
209 | size_t len) | ||
210 | { | ||
211 | int ret; | ||
212 | |||
213 | _enter("{%d,%s},", call->debug_id, rxrpc_call_states[call->state]); | ||
214 | |||
215 | ASSERTCMP(msg->msg_name, ==, NULL); | ||
216 | ASSERTCMP(msg->msg_control, ==, NULL); | ||
217 | |||
218 | lock_sock(&call->socket->sk); | ||
219 | |||
220 | _debug("CALL %d USR %lx ST %d on CONN %p", | ||
221 | call->debug_id, call->user_call_ID, call->state, call->conn); | ||
222 | |||
223 | if (call->state >= RXRPC_CALL_COMPLETE) { | ||
224 | ret = -ESHUTDOWN; /* it's too late for this call */ | ||
225 | } else if (call->state != RXRPC_CALL_CLIENT_SEND_REQUEST && | ||
226 | call->state != RXRPC_CALL_SERVER_ACK_REQUEST && | ||
227 | call->state != RXRPC_CALL_SERVER_SEND_REPLY) { | ||
228 | ret = -EPROTO; /* request phase complete for this client call */ | ||
229 | } else { | ||
230 | mm_segment_t oldfs = get_fs(); | ||
231 | set_fs(KERNEL_DS); | ||
232 | ret = rxrpc_send_data(NULL, call->socket, call, msg, len); | ||
233 | set_fs(oldfs); | ||
234 | } | ||
235 | |||
236 | release_sock(&call->socket->sk); | ||
237 | _leave(" = %d", ret); | ||
238 | return ret; | ||
239 | } | ||
240 | |||
241 | EXPORT_SYMBOL(rxrpc_kernel_send_data); | ||
242 | |||
243 | /* | ||
244 | * rxrpc_kernel_abort_call - Allow a kernel service to abort a call | ||
245 | * @call: The call to be aborted | ||
246 | * @abort_code: The abort code to stick into the ABORT packet | ||
247 | * | ||
248 | * Allow a kernel service to abort a call, if it's still in an abortable state. | ||
249 | */ | ||
250 | void rxrpc_kernel_abort_call(struct rxrpc_call *call, u32 abort_code) | ||
251 | { | ||
252 | _enter("{%d},%d", call->debug_id, abort_code); | ||
253 | |||
254 | lock_sock(&call->socket->sk); | ||
255 | |||
256 | _debug("CALL %d USR %lx ST %d on CONN %p", | ||
257 | call->debug_id, call->user_call_ID, call->state, call->conn); | ||
258 | |||
259 | if (call->state < RXRPC_CALL_COMPLETE) | ||
260 | rxrpc_send_abort(call, abort_code); | ||
261 | |||
262 | release_sock(&call->socket->sk); | ||
263 | _leave(""); | ||
264 | } | ||
265 | |||
266 | EXPORT_SYMBOL(rxrpc_kernel_abort_call); | ||
267 | |||
197 | /* | 268 | /* |
198 | * send a message through a server socket | 269 | * send a message through a server socket |
199 | * - caller holds the socket locked | 270 | * - caller holds the socket locked |
@@ -214,8 +285,13 @@ int rxrpc_server_sendmsg(struct kiocb *iocb, struct rxrpc_sock *rx, | |||
214 | if (ret < 0) | 285 | if (ret < 0) |
215 | return ret; | 286 | return ret; |
216 | 287 | ||
217 | if (cmd == RXRPC_CMD_ACCEPT) | 288 | if (cmd == RXRPC_CMD_ACCEPT) { |
218 | return rxrpc_accept_call(rx, user_call_ID); | 289 | call = rxrpc_accept_call(rx, user_call_ID); |
290 | if (IS_ERR(call)) | ||
291 | return PTR_ERR(call); | ||
292 | rxrpc_put_call(call); | ||
293 | return 0; | ||
294 | } | ||
219 | 295 | ||
220 | call = rxrpc_find_server_call(rx, user_call_ID); | 296 | call = rxrpc_find_server_call(rx, user_call_ID); |
221 | if (!call) | 297 | if (!call) |
@@ -363,7 +439,7 @@ static inline void rxrpc_instant_resend(struct rxrpc_call *call) | |||
363 | clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags); | 439 | clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags); |
364 | if (call->state < RXRPC_CALL_COMPLETE && | 440 | if (call->state < RXRPC_CALL_COMPLETE && |
365 | !test_and_set_bit(RXRPC_CALL_RESEND_TIMER, &call->events)) | 441 | !test_and_set_bit(RXRPC_CALL_RESEND_TIMER, &call->events)) |
366 | schedule_work(&call->processor); | 442 | rxrpc_queue_call(call); |
367 | } | 443 | } |
368 | read_unlock_bh(&call->state_lock); | 444 | read_unlock_bh(&call->state_lock); |
369 | } | 445 | } |