diff options
-rw-r--r-- | net/vmw_vsock/hyperv_transport.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c index 14ed5a344cdf..e21991fe883a 100644 --- a/net/vmw_vsock/hyperv_transport.c +++ b/net/vmw_vsock/hyperv_transport.c | |||
@@ -310,11 +310,15 @@ static void hvs_close_connection(struct vmbus_channel *chan) | |||
310 | struct sock *sk = get_per_channel_state(chan); | 310 | struct sock *sk = get_per_channel_state(chan); |
311 | struct vsock_sock *vsk = vsock_sk(sk); | 311 | struct vsock_sock *vsk = vsock_sk(sk); |
312 | 312 | ||
313 | lock_sock(sk); | ||
314 | |||
313 | sk->sk_state = SS_UNCONNECTED; | 315 | sk->sk_state = SS_UNCONNECTED; |
314 | sock_set_flag(sk, SOCK_DONE); | 316 | sock_set_flag(sk, SOCK_DONE); |
315 | vsk->peer_shutdown |= SEND_SHUTDOWN | RCV_SHUTDOWN; | 317 | vsk->peer_shutdown |= SEND_SHUTDOWN | RCV_SHUTDOWN; |
316 | 318 | ||
317 | sk->sk_state_change(sk); | 319 | sk->sk_state_change(sk); |
320 | |||
321 | release_sock(sk); | ||
318 | } | 322 | } |
319 | 323 | ||
320 | static void hvs_open_connection(struct vmbus_channel *chan) | 324 | static void hvs_open_connection(struct vmbus_channel *chan) |
@@ -344,6 +348,8 @@ static void hvs_open_connection(struct vmbus_channel *chan) | |||
344 | if (!sk) | 348 | if (!sk) |
345 | return; | 349 | return; |
346 | 350 | ||
351 | lock_sock(sk); | ||
352 | |||
347 | if ((conn_from_host && sk->sk_state != VSOCK_SS_LISTEN) || | 353 | if ((conn_from_host && sk->sk_state != VSOCK_SS_LISTEN) || |
348 | (!conn_from_host && sk->sk_state != SS_CONNECTING)) | 354 | (!conn_from_host && sk->sk_state != SS_CONNECTING)) |
349 | goto out; | 355 | goto out; |
@@ -395,9 +401,7 @@ static void hvs_open_connection(struct vmbus_channel *chan) | |||
395 | 401 | ||
396 | vsock_insert_connected(vnew); | 402 | vsock_insert_connected(vnew); |
397 | 403 | ||
398 | lock_sock(sk); | ||
399 | vsock_enqueue_accept(sk, new); | 404 | vsock_enqueue_accept(sk, new); |
400 | release_sock(sk); | ||
401 | } else { | 405 | } else { |
402 | sk->sk_state = SS_CONNECTED; | 406 | sk->sk_state = SS_CONNECTED; |
403 | sk->sk_socket->state = SS_CONNECTED; | 407 | sk->sk_socket->state = SS_CONNECTED; |
@@ -410,6 +414,8 @@ static void hvs_open_connection(struct vmbus_channel *chan) | |||
410 | out: | 414 | out: |
411 | /* Release refcnt obtained when we called vsock_find_bound_socket() */ | 415 | /* Release refcnt obtained when we called vsock_find_bound_socket() */ |
412 | sock_put(sk); | 416 | sock_put(sk); |
417 | |||
418 | release_sock(sk); | ||
413 | } | 419 | } |
414 | 420 | ||
415 | static u32 hvs_get_local_cid(void) | 421 | static u32 hvs_get_local_cid(void) |
@@ -476,13 +482,21 @@ out: | |||
476 | 482 | ||
477 | static void hvs_release(struct vsock_sock *vsk) | 483 | static void hvs_release(struct vsock_sock *vsk) |
478 | { | 484 | { |
485 | struct sock *sk = sk_vsock(vsk); | ||
479 | struct hvsock *hvs = vsk->trans; | 486 | struct hvsock *hvs = vsk->trans; |
480 | struct vmbus_channel *chan = hvs->chan; | 487 | struct vmbus_channel *chan; |
481 | 488 | ||
489 | lock_sock(sk); | ||
490 | |||
491 | sk->sk_state = SS_DISCONNECTING; | ||
492 | vsock_remove_sock(vsk); | ||
493 | |||
494 | release_sock(sk); | ||
495 | |||
496 | chan = hvs->chan; | ||
482 | if (chan) | 497 | if (chan) |
483 | hvs_shutdown(vsk, RCV_SHUTDOWN | SEND_SHUTDOWN); | 498 | hvs_shutdown(vsk, RCV_SHUTDOWN | SEND_SHUTDOWN); |
484 | 499 | ||
485 | vsock_remove_sock(vsk); | ||
486 | } | 500 | } |
487 | 501 | ||
488 | static void hvs_destruct(struct vsock_sock *vsk) | 502 | static void hvs_destruct(struct vsock_sock *vsk) |