diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2012-08-22 14:59:06 +0200 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-09 14:08:21 +0100 |
commit | b792b655cdf79d4d90b4d46fa37e260ba0296850 (patch) | |
tree | 3880fc3b0a90a1d83ab8e53c31efc10ff856bedc | |
parent | bc317a9ecd641b78a4b237cb22b30ecf11443c77 (diff) | |
download | op-kernel-dev-b792b655cdf79d4d90b4d46fa37e260ba0296850.zip op-kernel-dev-b792b655cdf79d4d90b4d46fa37e260ba0296850.tar.gz |
drbd: fix potential list_add corruption
If the md_sync_timer triggers a second time,
while the work queued during the first time is still pending,
this could result in list_add() of an already added item,
and corrupt the work item list.
This likely only triggered because of the erroneous
batch-dequeueing of work items fixed with
drbd: dequeue single work items in wait_for_work()
Still, skip queueing if md_sync_work is already queued.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index d831e85..732053d 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -3314,7 +3314,9 @@ static void md_sync_timer_fn(unsigned long data) { struct drbd_conf *mdev = (struct drbd_conf *) data; - drbd_queue_work_front(&mdev->tconn->sender_work, &mdev->md_sync_work); + /* must not double-queue! */ + if (list_empty(&mdev->md_sync_work.list)) + drbd_queue_work_front(&mdev->tconn->sender_work, &mdev->md_sync_work); } static int w_md_sync(struct drbd_work *w, int unused) |