@@ -339,6 +339,7 @@ static int start_readonly;
339339 * so all the races disappear.
340340 */
341341static bool create_on_open = true;
342+ static bool legacy_async_del_gendisk = true;
342343
343344/*
344345 * We have a system wide 'event count' that is incremented
@@ -877,15 +878,18 @@ void mddev_unlock(struct mddev *mddev)
877878 export_rdev (rdev , mddev );
878879 }
879880
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+ }
889893}
890894EXPORT_SYMBOL_GPL (mddev_unlock );
891895
@@ -1419,7 +1423,7 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *freshest, stru
14191423 else {
14201424 if (sb -> events_hi == sb -> cp_events_hi &&
14211425 sb -> events_lo == sb -> cp_events_lo ) {
1422- mddev -> resync_offset = sb -> resync_offset ;
1426+ mddev -> resync_offset = sb -> recovery_cp ;
14231427 } else
14241428 mddev -> resync_offset = 0 ;
14251429 }
@@ -1547,13 +1551,13 @@ static void super_90_sync(struct mddev *mddev, struct md_rdev *rdev)
15471551 mddev -> minor_version = sb -> minor_version ;
15481552 if (mddev -> in_sync )
15491553 {
1550- sb -> resync_offset = mddev -> resync_offset ;
1554+ sb -> recovery_cp = mddev -> resync_offset ;
15511555 sb -> cp_events_hi = (mddev -> events >>32 );
15521556 sb -> cp_events_lo = (u32 )mddev -> events ;
15531557 if (mddev -> resync_offset == MaxSector )
15541558 sb -> state = (1 << MD_SB_CLEAN );
15551559 } else
1556- sb -> resync_offset = 0 ;
1560+ sb -> recovery_cp = 0 ;
15571561
15581562 sb -> layout = mddev -> layout ;
15591563 sb -> chunk_size = mddev -> chunk_sectors << 9 ;
@@ -4835,9 +4839,42 @@ metadata_store(struct mddev *mddev, const char *buf, size_t len)
48354839static struct md_sysfs_entry md_metadata =
48364840__ATTR_PREALLOC (metadata_version , S_IRUGO |S_IWUSR , metadata_show , metadata_store );
48374841
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+
48384874enum sync_action md_sync_action (struct mddev * mddev )
48394875{
48404876 unsigned long recovery = mddev -> recovery ;
4877+ enum sync_action active_action ;
48414878
48424879 /*
48434880 * frozen has the highest priority, means running sync_thread will be
@@ -4861,8 +4898,17 @@ enum sync_action md_sync_action(struct mddev *mddev)
48614898 !test_bit (MD_RECOVERY_NEEDED , & recovery ))
48624899 return ACTION_IDLE ;
48634900
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 ))
48664912 return ACTION_RESHAPE ;
48674913
48684914 if (test_bit (MD_RECOVERY_RECOVER , & recovery ))
@@ -5818,6 +5864,13 @@ static void md_kobj_release(struct kobject *ko)
58185864{
58195865 struct mddev * mddev = container_of (ko , struct mddev , kobj );
58205866
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+ }
58215874 put_disk (mddev -> gendisk );
58225875}
58235876
@@ -6021,6 +6074,9 @@ static int md_alloc_and_put(dev_t dev, char *name)
60216074{
60226075 struct mddev * mddev = md_alloc (dev , name );
60236076
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+
60246080 if (IS_ERR (mddev ))
60256081 return PTR_ERR (mddev );
60266082 mddev_put (mddev );
@@ -6431,10 +6487,22 @@ static void md_clean(struct mddev *mddev)
64316487 mddev -> persistent = 0 ;
64326488 mddev -> level = LEVEL_NONE ;
64336489 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+ }
64386506 mddev -> sb_flags = 0 ;
64396507 mddev -> ro = MD_RDWR ;
64406508 mddev -> metadata_type [0 ] = 0 ;
@@ -6658,7 +6726,8 @@ static int do_md_stop(struct mddev *mddev, int mode)
66586726
66596727 export_array (mddev );
66606728 md_clean (mddev );
6661- set_bit (MD_DELETED , & mddev -> flags );
6729+ if (!legacy_async_del_gendisk )
6730+ set_bit (MD_DELETED , & mddev -> flags );
66626731 }
66636732 md_new_event ();
66646733 sysfs_notify_dirent_safe (mddev -> sysfs_state );
@@ -8968,11 +9037,7 @@ static sector_t md_sync_position(struct mddev *mddev, enum sync_action action)
89689037 start = MaxSector ;
89699038 rcu_read_lock ();
89709039 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 ))
89769041 start = rdev -> recovery_offset ;
89779042 rcu_read_unlock ();
89789043
@@ -9331,12 +9396,8 @@ void md_do_sync(struct md_thread *thread)
93319396 test_bit (MD_RECOVERY_RECOVER , & mddev -> recovery )) {
93329397 rcu_read_lock ();
93339398 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 ))
93409401 rdev -> recovery_offset = mddev -> curr_resync ;
93419402 rcu_read_unlock ();
93429403 }
@@ -10392,6 +10453,7 @@ module_param_call(start_ro, set_ro, get_ro, NULL, S_IRUSR|S_IWUSR);
1039210453module_param (start_dirty_degraded , int , S_IRUGO |S_IWUSR );
1039310454module_param_call (new_array , add_named_array , NULL , NULL , S_IWUSR );
1039410455module_param (create_on_open , bool , S_IRUSR |S_IWUSR );
10456+ module_param (legacy_async_del_gendisk , bool , 0600 );
1039510457
1039610458MODULE_LICENSE ("GPL" );
1039710459MODULE_DESCRIPTION ("MD RAID framework" );
0 commit comments