Commit 4589d7f8 authored by Lars Ellenberg's avatar Lars Ellenberg Committed by Philipp Reisner

drbd_disconnect: grab meta.socket mutex as well

Fixes a race and potential kernel panic if e.g. the worker was just
about to send a few P_RS_IS_IN_SYNC via the meta socket for checksum
based resync, while the receiver destroys the sockets in
drbd_disconnect.

To make sure no-one is using the meta socket,
it is not enough to stop the asender...
Grab the meta socket mutex before destroying it.
Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent 676396d5
...@@ -3173,14 +3173,18 @@ void drbd_free_bc(struct drbd_backing_dev *ldev) ...@@ -3173,14 +3173,18 @@ void drbd_free_bc(struct drbd_backing_dev *ldev)
void drbd_free_sock(struct drbd_conf *mdev) void drbd_free_sock(struct drbd_conf *mdev)
{ {
if (mdev->data.socket) { if (mdev->data.socket) {
mutex_lock(&mdev->data.mutex);
kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR); kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR);
sock_release(mdev->data.socket); sock_release(mdev->data.socket);
mdev->data.socket = NULL; mdev->data.socket = NULL;
mutex_unlock(&mdev->data.mutex);
} }
if (mdev->meta.socket) { if (mdev->meta.socket) {
mutex_lock(&mdev->meta.mutex);
kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR); kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR);
sock_release(mdev->meta.socket); sock_release(mdev->meta.socket);
mdev->meta.socket = NULL; mdev->meta.socket = NULL;
mutex_unlock(&mdev->meta.mutex);
} }
} }
......
...@@ -3617,10 +3617,7 @@ static void drbd_disconnect(struct drbd_conf *mdev) ...@@ -3617,10 +3617,7 @@ static void drbd_disconnect(struct drbd_conf *mdev)
/* asender does not clean up anything. it must not interfere, either */ /* asender does not clean up anything. it must not interfere, either */
drbd_thread_stop(&mdev->asender); drbd_thread_stop(&mdev->asender);
mutex_lock(&mdev->data.mutex);
drbd_free_sock(mdev); drbd_free_sock(mdev);
mutex_unlock(&mdev->data.mutex);
spin_lock_irq(&mdev->req_lock); spin_lock_irq(&mdev->req_lock);
_drbd_wait_ee_list_empty(mdev, &mdev->active_ee); _drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment