Patch "md/raid1: extend spinlock to protect raid1_end_read_request against inconsistencies" has been added to the 3.14-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
md/raid1: extend spinlock to protect raid1_end_read_request against inconsistencies
to the 3.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
md-raid1-extend-spinlock-to-protect-raid1_end_read_request-against-inconsistencies.patch
and it can be found in the queue-3.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
423f04d63cf421ea436bcc5be02543d549ce4b28Mon Sep 17 00:00:00 2001
From: NeilBrown <[email protected]>
Date: Mon, 27 Jul 2015 11:48:52 +1000
Subject: md/raid1: extend spinlock to protect raid1_end_read_request against inconsistencies
From: NeilBrown <[email protected]>
commit 423f04d63cf421ea436bcc5be02543d549ce4b28 upstream.
raid1_end_read_request() assumes that the In_sync bits are consistent with the ->degaded count.raid1_spare_active updates the In_sync bit before the ->degraded count and so exposes an inconsistency, as does error()
So extend the spinlock in raid1_spare_active() and error() to hide those inconsistencies.
This should probably be part of
Commit: 34cab6f42003 ("md/raid1: fix test for 'was read error from last working device'.")
as it addresses the same issue. It fixes the same bug and should go to -stable for same reasons.
--- drivers/md/raid1.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/md/raid1.c +6 -4
@@ -1477,6 +1477,7 @@ static void error(struct mddev *mddev, s {char b[BDEVNAME_SIZE ];struct r1conf *conf = mddev->private; +unsigned long flags;/* * If it is not operational, then we have already marked it as dead
@@ -1496,14 +1497,13 @@ static void error(struct mddev *mddev, sreturn ; }set_bit (Blocked, &rdev->flags); +spin_lock_irqsave (&conf->device_lock, flags);if (test_and_clear_bit (In_sync, &rdev->flags)) { -unsigned long flags; -spin_lock_irqsave (&conf->device_lock, flags); mddev->degraded++;set_bit (Faulty, &rdev->flags); -spin_unlock_irqrestore (&conf->device_lock, flags); }else set_bit (Faulty, &rdev->flags); +spin_unlock_irqrestore (&conf->device_lock, flags);/* * if recovery is running, make sure it aborts. */
@@ -1569,7 +1569,10 @@ static int raid1_spare_active(struct mdd* Find all failed disks within the RAID1 configuration * and mark them readable. * Called under mddev lock, so rcu protection not needed. +* device_lock used to avoid races with raid1_end_read_request +* which expects 'In_sync' flags and ->degraded to be consistent. */ +spin_lock_irqsave (&conf->device_lock, flags);for (i =0 ; i < conf->raid_disks; i++) {struct md_rdev *rdev = conf->mirrors[i].rdev;struct md_rdev *repl = conf->mirrors[conf->raid_disks + i].rdev;
@@ -1599,7 +1602,6 @@ static int raid1_spare_active(struct mddsysfs_notify_dirent_safe (rdev->sysfs_state); } } -spin_lock_irqsave (&conf->device_lock, flags); mddev->degraded -= count;spin_unlock_irqrestore (&conf->device_lock, flags);
Patches currently in stable-queue which might be from [email protected] are
queue-3.14/md-raid1-extend-spinlock-to-protect-raid1_end_read_request-against-inconsistencies.patch queue-3.14/md-use-kzalloc-when-bitmap-is-disabled.patch