浏览代码

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>
Dan Williams 15 年之前
父节点
当前提交
4e59ca7da0
共有 1 个文件被更改,包括 6 次插入2 次删除
  1. 6 2
      drivers/md/md.c

+ 6 - 2
drivers/md/md.c

@@ -6526,12 +6526,14 @@ void md_do_sync(mddev_t *mddev)
 		/* recovery follows the physical size of devices */
 		/* recovery follows the physical size of devices */
 		max_sectors = mddev->dev_sectors;
 		max_sectors = mddev->dev_sectors;
 		j = MaxSector;
 		j = MaxSector;
-		list_for_each_entry(rdev, &mddev->disks, same_set)
+		rcu_read_lock();
+		list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
 			if (rdev->raid_disk >= 0 &&
 			if (rdev->raid_disk >= 0 &&
 			    !test_bit(Faulty, &rdev->flags) &&
 			    !test_bit(Faulty, &rdev->flags) &&
 			    !test_bit(In_sync, &rdev->flags) &&
 			    !test_bit(In_sync, &rdev->flags) &&
 			    rdev->recovery_offset < j)
 			    rdev->recovery_offset < j)
 				j = rdev->recovery_offset;
 				j = rdev->recovery_offset;
+		rcu_read_unlock();
 	}
 	}
 
 
 	printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev));
 	printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev));
@@ -6701,12 +6703,14 @@ void md_do_sync(mddev_t *mddev)
 		} else {
 		} else {
 			if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery))
 			if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery))
 				mddev->curr_resync = MaxSector;
 				mddev->curr_resync = MaxSector;
-			list_for_each_entry(rdev, &mddev->disks, same_set)
+			rcu_read_lock();
+			list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
 				if (rdev->raid_disk >= 0 &&
 				if (rdev->raid_disk >= 0 &&
 				    !test_bit(Faulty, &rdev->flags) &&
 				    !test_bit(Faulty, &rdev->flags) &&
 				    !test_bit(In_sync, &rdev->flags) &&
 				    !test_bit(In_sync, &rdev->flags) &&
 				    rdev->recovery_offset < mddev->curr_resync)
 				    rdev->recovery_offset < mddev->curr_resync)
 					rdev->recovery_offset = mddev->curr_resync;
 					rdev->recovery_offset = mddev->curr_resync;
+			rcu_read_unlock();
 		}
 		}
 	}
 	}
 	set_bit(MD_CHANGE_DEVS, &mddev->flags);
 	set_bit(MD_CHANGE_DEVS, &mddev->flags);