From e42a80dda652a3eb68ae427e19b7131929ccd85b Mon Sep 17 00:00:00 2001 From: Hyunjun Lee Date: Tue, 14 Feb 2017 16:39:07 +0900 Subject: [PATCH 1/2] DW-1398 Implementing irp cancel routine. --- wdrbd9/wsk2.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/wdrbd9/wsk2.c b/wdrbd9/wsk2.c index eb2bdfc4..11b5e4a4 100644 --- a/wdrbd9/wsk2.c +++ b/wdrbd9/wsk2.c @@ -44,6 +44,18 @@ NTAPI CompletionRoutineAsync( } #endif +// DW-1398: Implementing a cancel routine. +VOID CancelRoutine( + IN PDEVICE_OBJECT pDeviceObject, + IN PIRP Irp) +{ + IoReleaseCancelSpinLock(Irp->CancelIrql); + Irp->IoStatus.Status = STATUS_CANCELLED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} + NTSTATUS InitWskData( __out PIRP* pIrp, @@ -51,6 +63,8 @@ InitWskData( __in BOOLEAN bRawIrp ) { + KIRQL irql; + ASSERT(pIrp); ASSERT(CompletionEvent); @@ -69,6 +83,11 @@ InitWskData( KeInitializeEvent(CompletionEvent, SynchronizationEvent, FALSE); IoSetCompletionRoutine(*pIrp, CompletionRoutine, CompletionEvent, TRUE, TRUE, TRUE); + + // DW-1398: set cancel routine + IoAcquireCancelSpinLock(&irql); + IoSetCancelRoutine(*pIrp, CancelRoutine); + IoReleaseCancelSpinLock(irql); return STATUS_SUCCESS; } @@ -81,6 +100,8 @@ InitWskDataAsync( __in BOOLEAN bRawIrp ) { + KIRQL irql; + ASSERT(pIrp); ASSERT(CompletionEvent); @@ -99,6 +120,11 @@ InitWskDataAsync( //KeInitializeEvent(CompletionEvent, SynchronizationEvent, FALSE); IoSetCompletionRoutine(*pIrp, CompletionRoutineAsync, NULL, TRUE, TRUE, TRUE); + // DW-1398: set cancel routine + IoAcquireCancelSpinLock(&irql); + IoSetCancelRoutine(*pIrp, CancelRoutine); + IoReleaseCancelSpinLock(irql); + return STATUS_SUCCESS; } #endif @@ -109,6 +135,8 @@ __out PIRP* pIrp, __out PKEVENT CompletionEvent ) { + KIRQL irql; + ASSERT(pIrp); ASSERT(CompletionEvent); @@ -116,6 +144,11 @@ __out PKEVENT CompletionEvent IoReuseIrp(*pIrp, STATUS_UNSUCCESSFUL); IoSetCompletionRoutine(*pIrp, CompletionRoutine, CompletionEvent, TRUE, TRUE, TRUE); + // DW-1398: set cancel routine + IoAcquireCancelSpinLock(&irql); + IoSetCancelRoutine(*pIrp, CancelRoutine); + IoReleaseCancelSpinLock(irql); + return; } From 75ec335005aca4eef533f64466c0313e9cdca14c Mon Sep 17 00:00:00 2001 From: Hyunjun Lee Date: Tue, 14 Feb 2017 17:23:32 +0900 Subject: [PATCH 2/2] DW-1398 move putting lister to conn_disconnect() closing listening socket busts accepted socket, put those sockets when disconnecting instead. --- drbd-headers/drbd_transport.h | 2 ++ drbd/drbd_int.h | 5 +++++ drbd/drbd_receiver.c | 5 +++++ drbd/drbd_transport_tcp.c | 23 ++++++++++++++++++++++- 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/drbd-headers/drbd_transport.h b/drbd-headers/drbd_transport.h index ec941957..f61dc0d7 100644 --- a/drbd-headers/drbd_transport.h +++ b/drbd-headers/drbd_transport.h @@ -146,6 +146,8 @@ struct drbd_transport { #ifdef _WIN32 atomic_t listening; + // DW-1398: accepted all peers and listening socket is no longer available. + atomic_t listening_done; #endif }; diff --git a/drbd/drbd_int.h b/drbd/drbd_int.h index 4c1ebec0..5a8e5676 100644 --- a/drbd/drbd_int.h +++ b/drbd/drbd_int.h @@ -2309,6 +2309,11 @@ extern struct drbd_resource *drbd_find_resource(const char *name); extern void drbd_destroy_resource(struct kref *kref); extern void conn_free_crypto(struct drbd_connection *connection); +#ifdef _WIN32 +// DW-1398 +extern void dtt_put_listeners(struct drbd_transport *); +#endif + /* drbd_req */ extern void do_submit(struct work_struct *ws); #ifdef _WIN32 diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c index 195a27f3..9c6da610 100644 --- a/drbd/drbd_receiver.c +++ b/drbd/drbd_receiver.c @@ -8062,6 +8062,11 @@ void conn_disconnect(struct drbd_connection *connection) change_cstate(connection, C_NETWORK_FAILURE, CS_HARD); +#ifdef _WIN32 + // DW-1398: closing listening socket busts accepted socket, put those sockets here instead. + dtt_put_listeners(&connection->transport); +#endif + del_connect_timer(connection); /* ack_receiver does not clean up anything. it must not interfere, either */ diff --git a/drbd/drbd_transport_tcp.c b/drbd/drbd_transport_tcp.c index 16f809ef..3377f437 100644 --- a/drbd/drbd_transport_tcp.c +++ b/drbd/drbd_transport_tcp.c @@ -1238,6 +1238,19 @@ static void dtt_incoming_connection(struct sock *sock) spin_unlock(&listener->listener.waiters_lock); return STATUS_REQUEST_NOT_ACCEPTED; } + +#ifdef _WIN32 + // DW-1398: do not accept if already connected. + if (atomic_read(&waiter->transport->listening_done)) + { + WDRBD_WARN("listening is done for this transport, request won't be accepted\n"); + kfree(s_estab->sk_linux_attr); + kfree(s_estab); + spin_unlock(&listener->listener.waiters_lock); + return STATUS_REQUEST_NOT_ACCEPTED; + } +#endif + struct dtt_path * path = container_of(waiter, struct dtt_path, waiter); if (path) @@ -1517,6 +1530,8 @@ static int dtt_create_listener(struct drbd_transport *transport, err = -1; goto out; } + // DW-1398: initialize. + atomic_set(&transport->listening_done, false); #endif return 0; out: @@ -1547,7 +1562,12 @@ static void dtt_cleanup_accepted_sockets(struct dtt_path *path) } #endif +#ifdef _WIN32 +// DW-1398 +void dtt_put_listeners(struct drbd_transport *transport) +#else static void dtt_put_listeners(struct drbd_transport *transport) +#endif { struct drbd_tcp_transport *tcp_transport = container_of(transport, struct drbd_tcp_transport, transport); @@ -1852,7 +1872,8 @@ static int dtt_connect(struct drbd_transport *transport) connect_to_path->path.established = true; drbd_path_event(transport, &connect_to_path->path); #ifdef _WIN32 - dtt_put_listeners(transport); + // DW-1398: closing listening socket here makes accepted socket be unavailable, putting listeners is moved to conn_disconnect() + atomic_set(&transport->listening_done, true); #else dtt_put_listeners(transport); #endif