diff options
| author | Dan Williams <dan.j.williams@intel.com> | 2009-12-12 23:17:06 -0500 |
|---|---|---|
| committer | NeilBrown <neilb@suse.de> | 2009-12-13 20:57:43 -0500 |
| commit | 4e59ca7da05f0d5d3ad40365c502c8b0fd24c7e3 (patch) | |
| tree | d5ddc749ec13db16c1ed7a054546c2ea482c0e1e | |
| parent | 93be75ffde6dfd1ad17cc3ff1dbd135bd711baf4 (diff) | |
md: rcu_read_lock() walk of mddev->disks in md_do_sync()
Other walks of this list are either under rcu_read_lock() or the list
mutation lock (mddev_lock()). This protects against the improbable case of a
disk being removed from the array at the start of md_do_sync().
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
| -rw-r--r-- | drivers/md/md.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 68a8a29a9012..ea64a68e9c75 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -6526,12 +6526,14 @@ void md_do_sync(mddev_t *mddev) | |||
| 6526 | /* recovery follows the physical size of devices */ | 6526 | /* recovery follows the physical size of devices */ |
| 6527 | max_sectors = mddev->dev_sectors; | 6527 | max_sectors = mddev->dev_sectors; |
| 6528 | j = MaxSector; | 6528 | j = MaxSector; |
| 6529 | list_for_each_entry(rdev, &mddev->disks, same_set) | 6529 | rcu_read_lock(); |
| 6530 | list_for_each_entry_rcu(rdev, &mddev->disks, same_set) | ||
| 6530 | if (rdev->raid_disk >= 0 && | 6531 | if (rdev->raid_disk >= 0 && |
| 6531 | !test_bit(Faulty, &rdev->flags) && | 6532 | !test_bit(Faulty, &rdev->flags) && |
| 6532 | !test_bit(In_sync, &rdev->flags) && | 6533 | !test_bit(In_sync, &rdev->flags) && |
| 6533 | rdev->recovery_offset < j) | 6534 | rdev->recovery_offset < j) |
| 6534 | j = rdev->recovery_offset; | 6535 | j = rdev->recovery_offset; |
| 6536 | rcu_read_unlock(); | ||
| 6535 | } | 6537 | } |
| 6536 | 6538 | ||
| 6537 | printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev)); | 6539 | printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev)); |
| @@ -6701,12 +6703,14 @@ void md_do_sync(mddev_t *mddev) | |||
| 6701 | } else { | 6703 | } else { |
| 6702 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) | 6704 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) |
| 6703 | mddev->curr_resync = MaxSector; | 6705 | mddev->curr_resync = MaxSector; |
| 6704 | list_for_each_entry(rdev, &mddev->disks, same_set) | 6706 | rcu_read_lock(); |
| 6707 | list_for_each_entry_rcu(rdev, &mddev->disks, same_set) | ||
| 6705 | if (rdev->raid_disk >= 0 && | 6708 | if (rdev->raid_disk >= 0 && |
| 6706 | !test_bit(Faulty, &rdev->flags) && | 6709 | !test_bit(Faulty, &rdev->flags) && |
| 6707 | !test_bit(In_sync, &rdev->flags) && | 6710 | !test_bit(In_sync, &rdev->flags) && |
| 6708 | rdev->recovery_offset < mddev->curr_resync) | 6711 | rdev->recovery_offset < mddev->curr_resync) |
| 6709 | rdev->recovery_offset = mddev->curr_resync; | 6712 | rdev->recovery_offset = mddev->curr_resync; |
| 6713 | rcu_read_unlock(); | ||
| 6710 | } | 6714 | } |
| 6711 | } | 6715 | } |
| 6712 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 6716 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
