@@ -339,6 +339,7 @@ static int start_readonly;
339
339
* so all the races disappear.
340
340
*/
341
341
static bool create_on_open = true;
342
+ static bool legacy_async_del_gendisk = true;
342
343
343
344
/*
344
345
* We have a system wide 'event count' that is incremented
@@ -877,15 +878,18 @@ void mddev_unlock(struct mddev *mddev)
877
878
export_rdev (rdev , mddev );
878
879
}
879
880
880
- /* Call del_gendisk after release reconfig_mutex to avoid
881
- * deadlock (e.g. call del_gendisk under the lock and an
882
- * access to sysfs files waits the lock)
883
- * And MD_DELETED is only used for md raid which is set in
884
- * do_md_stop. dm raid only uses md_stop to stop. So dm raid
885
- * doesn't need to check MD_DELETED when getting reconfig lock
886
- */
887
- if (test_bit (MD_DELETED , & mddev -> flags ))
888
- del_gendisk (mddev -> gendisk );
881
+ if (!legacy_async_del_gendisk ) {
882
+ /*
883
+ * Call del_gendisk after release reconfig_mutex to avoid
884
+ * deadlock (e.g. call del_gendisk under the lock and an
885
+ * access to sysfs files waits the lock)
886
+ * And MD_DELETED is only used for md raid which is set in
887
+ * do_md_stop. dm raid only uses md_stop to stop. So dm raid
888
+ * doesn't need to check MD_DELETED when getting reconfig lock
889
+ */
890
+ if (test_bit (MD_DELETED , & mddev -> flags ))
891
+ del_gendisk (mddev -> gendisk );
892
+ }
889
893
}
890
894
EXPORT_SYMBOL_GPL (mddev_unlock );
891
895
@@ -1419,7 +1423,7 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *freshest, stru
1419
1423
else {
1420
1424
if (sb -> events_hi == sb -> cp_events_hi &&
1421
1425
sb -> events_lo == sb -> cp_events_lo ) {
1422
- mddev -> resync_offset = sb -> resync_offset ;
1426
+ mddev -> resync_offset = sb -> recovery_cp ;
1423
1427
} else
1424
1428
mddev -> resync_offset = 0 ;
1425
1429
}
@@ -1547,13 +1551,13 @@ static void super_90_sync(struct mddev *mddev, struct md_rdev *rdev)
1547
1551
mddev -> minor_version = sb -> minor_version ;
1548
1552
if (mddev -> in_sync )
1549
1553
{
1550
- sb -> resync_offset = mddev -> resync_offset ;
1554
+ sb -> recovery_cp = mddev -> resync_offset ;
1551
1555
sb -> cp_events_hi = (mddev -> events >>32 );
1552
1556
sb -> cp_events_lo = (u32 )mddev -> events ;
1553
1557
if (mddev -> resync_offset == MaxSector )
1554
1558
sb -> state = (1 << MD_SB_CLEAN );
1555
1559
} else
1556
- sb -> resync_offset = 0 ;
1560
+ sb -> recovery_cp = 0 ;
1557
1561
1558
1562
sb -> layout = mddev -> layout ;
1559
1563
sb -> chunk_size = mddev -> chunk_sectors << 9 ;
@@ -4835,9 +4839,42 @@ metadata_store(struct mddev *mddev, const char *buf, size_t len)
4835
4839
static struct md_sysfs_entry md_metadata =
4836
4840
__ATTR_PREALLOC (metadata_version , S_IRUGO |S_IWUSR , metadata_show , metadata_store );
4837
4841
4842
+ static bool rdev_needs_recovery (struct md_rdev * rdev , sector_t sectors )
4843
+ {
4844
+ return rdev -> raid_disk >= 0 &&
4845
+ !test_bit (Journal , & rdev -> flags ) &&
4846
+ !test_bit (Faulty , & rdev -> flags ) &&
4847
+ !test_bit (In_sync , & rdev -> flags ) &&
4848
+ rdev -> recovery_offset < sectors ;
4849
+ }
4850
+
4851
+ static enum sync_action md_get_active_sync_action (struct mddev * mddev )
4852
+ {
4853
+ struct md_rdev * rdev ;
4854
+ bool is_recover = false;
4855
+
4856
+ if (mddev -> resync_offset < MaxSector )
4857
+ return ACTION_RESYNC ;
4858
+
4859
+ if (mddev -> reshape_position != MaxSector )
4860
+ return ACTION_RESHAPE ;
4861
+
4862
+ rcu_read_lock ();
4863
+ rdev_for_each_rcu (rdev , mddev ) {
4864
+ if (rdev_needs_recovery (rdev , MaxSector )) {
4865
+ is_recover = true;
4866
+ break ;
4867
+ }
4868
+ }
4869
+ rcu_read_unlock ();
4870
+
4871
+ return is_recover ? ACTION_RECOVER : ACTION_IDLE ;
4872
+ }
4873
+
4838
4874
enum sync_action md_sync_action (struct mddev * mddev )
4839
4875
{
4840
4876
unsigned long recovery = mddev -> recovery ;
4877
+ enum sync_action active_action ;
4841
4878
4842
4879
/*
4843
4880
* frozen has the highest priority, means running sync_thread will be
@@ -4861,8 +4898,17 @@ enum sync_action md_sync_action(struct mddev *mddev)
4861
4898
!test_bit (MD_RECOVERY_NEEDED , & recovery ))
4862
4899
return ACTION_IDLE ;
4863
4900
4864
- if (test_bit (MD_RECOVERY_RESHAPE , & recovery ) ||
4865
- mddev -> reshape_position != MaxSector )
4901
+ /*
4902
+ * Check if any sync operation (resync/recover/reshape) is
4903
+ * currently active. This ensures that only one sync operation
4904
+ * can run at a time. Returns the type of active operation, or
4905
+ * ACTION_IDLE if none are active.
4906
+ */
4907
+ active_action = md_get_active_sync_action (mddev );
4908
+ if (active_action != ACTION_IDLE )
4909
+ return active_action ;
4910
+
4911
+ if (test_bit (MD_RECOVERY_RESHAPE , & recovery ))
4866
4912
return ACTION_RESHAPE ;
4867
4913
4868
4914
if (test_bit (MD_RECOVERY_RECOVER , & recovery ))
@@ -5818,6 +5864,13 @@ static void md_kobj_release(struct kobject *ko)
5818
5864
{
5819
5865
struct mddev * mddev = container_of (ko , struct mddev , kobj );
5820
5866
5867
+ if (legacy_async_del_gendisk ) {
5868
+ if (mddev -> sysfs_state )
5869
+ sysfs_put (mddev -> sysfs_state );
5870
+ if (mddev -> sysfs_level )
5871
+ sysfs_put (mddev -> sysfs_level );
5872
+ del_gendisk (mddev -> gendisk );
5873
+ }
5821
5874
put_disk (mddev -> gendisk );
5822
5875
}
5823
5876
@@ -6021,6 +6074,9 @@ static int md_alloc_and_put(dev_t dev, char *name)
6021
6074
{
6022
6075
struct mddev * mddev = md_alloc (dev , name );
6023
6076
6077
+ if (legacy_async_del_gendisk )
6078
+ pr_warn ("md: async del_gendisk mode will be removed in future, please upgrade to mdadm-4.5+\n" );
6079
+
6024
6080
if (IS_ERR (mddev ))
6025
6081
return PTR_ERR (mddev );
6026
6082
mddev_put (mddev );
@@ -6431,10 +6487,22 @@ static void md_clean(struct mddev *mddev)
6431
6487
mddev -> persistent = 0 ;
6432
6488
mddev -> level = LEVEL_NONE ;
6433
6489
mddev -> clevel [0 ] = 0 ;
6434
- /* if UNTIL_STOP is set, it's cleared here */
6435
- mddev -> hold_active = 0 ;
6436
- /* Don't clear MD_CLOSING, or mddev can be opened again. */
6437
- mddev -> flags &= BIT_ULL_MASK (MD_CLOSING );
6490
+
6491
+ /*
6492
+ * For legacy_async_del_gendisk mode, it can stop the array in the
6493
+ * middle of assembling it, then it still can access the array. So
6494
+ * it needs to clear MD_CLOSING. If not legacy_async_del_gendisk,
6495
+ * it can't open the array again after stopping it. So it doesn't
6496
+ * clear MD_CLOSING.
6497
+ */
6498
+ if (legacy_async_del_gendisk && mddev -> hold_active ) {
6499
+ clear_bit (MD_CLOSING , & mddev -> flags );
6500
+ } else {
6501
+ /* if UNTIL_STOP is set, it's cleared here */
6502
+ mddev -> hold_active = 0 ;
6503
+ /* Don't clear MD_CLOSING, or mddev can be opened again. */
6504
+ mddev -> flags &= BIT_ULL_MASK (MD_CLOSING );
6505
+ }
6438
6506
mddev -> sb_flags = 0 ;
6439
6507
mddev -> ro = MD_RDWR ;
6440
6508
mddev -> metadata_type [0 ] = 0 ;
@@ -6658,7 +6726,8 @@ static int do_md_stop(struct mddev *mddev, int mode)
6658
6726
6659
6727
export_array (mddev );
6660
6728
md_clean (mddev );
6661
- set_bit (MD_DELETED , & mddev -> flags );
6729
+ if (!legacy_async_del_gendisk )
6730
+ set_bit (MD_DELETED , & mddev -> flags );
6662
6731
}
6663
6732
md_new_event ();
6664
6733
sysfs_notify_dirent_safe (mddev -> sysfs_state );
@@ -8968,11 +9037,7 @@ static sector_t md_sync_position(struct mddev *mddev, enum sync_action action)
8968
9037
start = MaxSector ;
8969
9038
rcu_read_lock ();
8970
9039
rdev_for_each_rcu (rdev , mddev )
8971
- if (rdev -> raid_disk >= 0 &&
8972
- !test_bit (Journal , & rdev -> flags ) &&
8973
- !test_bit (Faulty , & rdev -> flags ) &&
8974
- !test_bit (In_sync , & rdev -> flags ) &&
8975
- rdev -> recovery_offset < start )
9040
+ if (rdev_needs_recovery (rdev , start ))
8976
9041
start = rdev -> recovery_offset ;
8977
9042
rcu_read_unlock ();
8978
9043
@@ -9331,12 +9396,8 @@ void md_do_sync(struct md_thread *thread)
9331
9396
test_bit (MD_RECOVERY_RECOVER , & mddev -> recovery )) {
9332
9397
rcu_read_lock ();
9333
9398
rdev_for_each_rcu (rdev , mddev )
9334
- if (rdev -> raid_disk >= 0 &&
9335
- mddev -> delta_disks >= 0 &&
9336
- !test_bit (Journal , & rdev -> flags ) &&
9337
- !test_bit (Faulty , & rdev -> flags ) &&
9338
- !test_bit (In_sync , & rdev -> flags ) &&
9339
- rdev -> recovery_offset < mddev -> curr_resync )
9399
+ if (mddev -> delta_disks >= 0 &&
9400
+ rdev_needs_recovery (rdev , mddev -> curr_resync ))
9340
9401
rdev -> recovery_offset = mddev -> curr_resync ;
9341
9402
rcu_read_unlock ();
9342
9403
}
@@ -10392,6 +10453,7 @@ module_param_call(start_ro, set_ro, get_ro, NULL, S_IRUSR|S_IWUSR);
10392
10453
module_param (start_dirty_degraded , int , S_IRUGO |S_IWUSR );
10393
10454
module_param_call (new_array , add_named_array , NULL , NULL , S_IWUSR );
10394
10455
module_param (create_on_open , bool , S_IRUSR |S_IWUSR );
10456
+ module_param (legacy_async_del_gendisk , bool , 0600 );
10395
10457
10396
10458
MODULE_LICENSE ("GPL" );
10397
10459
MODULE_DESCRIPTION ("MD RAID framework" );
0 commit comments