From 58855766279403b4df676a1dc7b6c672fe027ffb Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Wed, 3 Mar 2010 02:25:33 +0100 Subject: [PATCH 09/16] 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. --- drbd/drbd_main.c | 4 ++++ drbd/drbd_receiver.c | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c index 3a5b942..0a3dac0 100644 --- a/drbd/drbd_main.c +++ b/drbd/drbd_main.c @@ -3384,14 +3384,18 @@ void drbd_free_bc(struct drbd_backing_dev *ldev) void drbd_free_sock(struct drbd_conf *mdev) { if (mdev->data.socket) { + mutex_lock(&mdev->data.mutex); kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR); sock_release(mdev->data.socket); mdev->data.socket = NULL; + mutex_unlock(&mdev->data.mutex); } if (mdev->meta.socket) { + mutex_lock(&mdev->meta.mutex); kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR); sock_release(mdev->meta.socket); mdev->meta.socket = NULL; + mutex_unlock(&mdev->meta.mutex); } } diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c index a9469b4..3b123a6 100644 --- a/drbd/drbd_receiver.c +++ b/drbd/drbd_receiver.c @@ -3668,10 +3668,7 @@ STATIC void drbd_disconnect(struct drbd_conf *mdev) /* asender does not clean up anything. it must not interfere, either */ drbd_thread_stop(&mdev->asender); - - mutex_lock(&mdev->data.mutex); drbd_free_sock(mdev); - mutex_unlock(&mdev->data.mutex); spin_lock_irq(&mdev->req_lock); _drbd_wait_ee_list_empty(mdev, &mdev->active_ee); -- 1.6.3.3