Skip to content

Commit 829451b

Browse files
author
Mikulas Patocka
committed
dm-mirror: fix a tiny race condition
There's a tiny race condition in dm-mirror. The functions queue_bio and write_callback grab a spinlock, add a bio to the list, drop the spinlock and wake up the mirrord thread that processes bios in the list. It may be possible that the mirrord thread processes the bio just after spin_unlock_irqrestore is called, before wakeup_mirrord. This spurious wake-up is normally harmless, however if the device mapper device is unloaded just after the bio was processed, it may be possible that wakeup_mirrord(ms) uses invalid "ms" pointer. Fix this bug by moving wakeup_mirrord inside the spinlock. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org
1 parent 85f6d5b commit 829451b

File tree

1 file changed

+2
-3
lines changed

1 file changed

+2
-3
lines changed

drivers/md/dm-raid1.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,9 @@ static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw)
133133
spin_lock_irqsave(&ms->lock, flags);
134134
should_wake = !(bl->head);
135135
bio_list_add(bl, bio);
136-
spin_unlock_irqrestore(&ms->lock, flags);
137-
138136
if (should_wake)
139137
wakeup_mirrord(ms);
138+
spin_unlock_irqrestore(&ms->lock, flags);
140139
}
141140

142141
static void dispatch_bios(void *context, struct bio_list *bio_list)
@@ -646,9 +645,9 @@ static void write_callback(unsigned long error, void *context)
646645
if (!ms->failures.head)
647646
should_wake = 1;
648647
bio_list_add(&ms->failures, bio);
649-
spin_unlock_irqrestore(&ms->lock, flags);
650648
if (should_wake)
651649
wakeup_mirrord(ms);
650+
spin_unlock_irqrestore(&ms->lock, flags);
652651
}
653652

654653
static void do_write(struct mirror_set *ms, struct bio *bio)

0 commit comments

Comments
 (0)