|
@@ -1628,11 +1628,20 @@ static int work_start(void)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static void stop_conn(struct connection *con)
|
|
|
|
|
|
+static void _stop_conn(struct connection *con, bool and_other)
|
|
{
|
|
{
|
|
- con->flags |= 0x0F;
|
|
|
|
|
|
+ mutex_lock(&con->sock_mutex);
|
|
|
|
+ set_bit(CF_READ_PENDING, &con->flags);
|
|
if (con->sock && con->sock->sk)
|
|
if (con->sock && con->sock->sk)
|
|
con->sock->sk->sk_user_data = NULL;
|
|
con->sock->sk->sk_user_data = NULL;
|
|
|
|
+ if (con->othercon && and_other)
|
|
|
|
+ _stop_conn(con->othercon, false);
|
|
|
|
+ mutex_unlock(&con->sock_mutex);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void stop_conn(struct connection *con)
|
|
|
|
+{
|
|
|
|
+ _stop_conn(con, true);
|
|
}
|
|
}
|
|
|
|
|
|
static void free_conn(struct connection *con)
|
|
static void free_conn(struct connection *con)
|
|
@@ -1644,6 +1653,32 @@ static void free_conn(struct connection *con)
|
|
kmem_cache_free(con_cache, con);
|
|
kmem_cache_free(con_cache, con);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void work_flush(void)
|
|
|
|
+{
|
|
|
|
+ int ok;
|
|
|
|
+ int i;
|
|
|
|
+ struct hlist_node *n;
|
|
|
|
+ struct connection *con;
|
|
|
|
+
|
|
|
|
+ flush_workqueue(recv_workqueue);
|
|
|
|
+ flush_workqueue(send_workqueue);
|
|
|
|
+ do {
|
|
|
|
+ ok = 1;
|
|
|
|
+ foreach_conn(stop_conn);
|
|
|
|
+ flush_workqueue(recv_workqueue);
|
|
|
|
+ flush_workqueue(send_workqueue);
|
|
|
|
+ for (i = 0; i < CONN_HASH_SIZE && ok; i++) {
|
|
|
|
+ hlist_for_each_entry_safe(con, n,
|
|
|
|
+ &connection_hash[i], list) {
|
|
|
|
+ ok &= test_bit(CF_READ_PENDING, &con->flags);
|
|
|
|
+ if (con->othercon)
|
|
|
|
+ ok &= test_bit(CF_READ_PENDING,
|
|
|
|
+ &con->othercon->flags);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } while (!ok);
|
|
|
|
+}
|
|
|
|
+
|
|
void dlm_lowcomms_stop(void)
|
|
void dlm_lowcomms_stop(void)
|
|
{
|
|
{
|
|
/* Set all the flags to prevent any
|
|
/* Set all the flags to prevent any
|
|
@@ -1651,11 +1686,10 @@ void dlm_lowcomms_stop(void)
|
|
*/
|
|
*/
|
|
mutex_lock(&connections_lock);
|
|
mutex_lock(&connections_lock);
|
|
dlm_allow_conn = 0;
|
|
dlm_allow_conn = 0;
|
|
- foreach_conn(stop_conn);
|
|
|
|
|
|
+ mutex_unlock(&connections_lock);
|
|
|
|
+ work_flush();
|
|
clean_writequeues();
|
|
clean_writequeues();
|
|
foreach_conn(free_conn);
|
|
foreach_conn(free_conn);
|
|
- mutex_unlock(&connections_lock);
|
|
|
|
-
|
|
|
|
work_stop();
|
|
work_stop();
|
|
|
|
|
|
kmem_cache_destroy(con_cache);
|
|
kmem_cache_destroy(con_cache);
|