Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'md-6.17-20250819' of gitolite.kernel.org:pub/scm/linux/kernel/git/mdraid/linux into block-6.17

Pull MD fixes from Yu:

"- Add a legacy_async_del_gendisk mode, to prevent a user tools
regression. New user tools releases will not use such a mode, the old
release with a new kernel now will have warning about deprecated
behavior, and we prepare to remove this legacy mode after about a
year later.
- The rename in kernel causing user tools build failure, revert the
rename in mdp_superblock_s.
- Fix a regression that interrupted resync can be shown as recover from
mdstat or sysfs."

* tag 'md-6.17-20250819' of gitolite.kernel.org:pub/scm/linux/kernel/git/mdraid/linux:
md: fix sync_action incorrect display during resync
md: add helper rdev_needs_recovery()
md: keep recovery_cp in mdp_superblock_s
md: add legacy_async_del_gendisk mode

Jens Axboe 72421690 f4ae1744

+93 -31
+92 -30
drivers/md/md.c
··· 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 ··· 878 877 export_rdev(rdev, mddev); 879 878 } 880 879 881 - /* Call del_gendisk after release reconfig_mutex to avoid 882 - * deadlock (e.g. call del_gendisk under the lock and an 883 - * access to sysfs files waits the lock) 884 - * And MD_DELETED is only used for md raid which is set in 885 - * do_md_stop. dm raid only uses md_stop to stop. So dm raid 886 - * doesn't need to check MD_DELETED when getting reconfig lock 887 - */ 888 - if (test_bit(MD_DELETED, &mddev->flags)) 889 - del_gendisk(mddev->gendisk); 880 + if (!legacy_async_del_gendisk) { 881 + /* 882 + * Call del_gendisk after release reconfig_mutex to avoid 883 + * deadlock (e.g. call del_gendisk under the lock and an 884 + * access to sysfs files waits the lock) 885 + * And MD_DELETED is only used for md raid which is set in 886 + * do_md_stop. dm raid only uses md_stop to stop. So dm raid 887 + * doesn't need to check MD_DELETED when getting reconfig lock 888 + */ 889 + if (test_bit(MD_DELETED, &mddev->flags)) 890 + del_gendisk(mddev->gendisk); 891 + } 890 892 } 891 893 EXPORT_SYMBOL_GPL(mddev_unlock); 892 894 ··· 1423 1419 else { 1424 1420 if (sb->events_hi == sb->cp_events_hi && 1425 1421 sb->events_lo == sb->cp_events_lo) { 1426 - mddev->resync_offset = sb->resync_offset; 1422 + mddev->resync_offset = sb->recovery_cp; 1427 1423 } else 1428 1424 mddev->resync_offset = 0; 1429 1425 } ··· 1551 1547 mddev->minor_version = sb->minor_version; 1552 1548 if (mddev->in_sync) 1553 1549 { 1554 - sb->resync_offset = mddev->resync_offset; 1550 + sb->recovery_cp = mddev->resync_offset; 1555 1551 sb->cp_events_hi = (mddev->events>>32); 1556 1552 sb->cp_events_lo = (u32)mddev->events; 1557 1553 if (mddev->resync_offset == MaxSector) 1558 1554 sb->state = (1<< MD_SB_CLEAN); 1559 1555 } else 1560 - sb->resync_offset = 0; 1556 + sb->recovery_cp = 0; 1561 1557 1562 1558 sb->layout = mddev->layout; 1563 1559 sb->chunk_size = mddev->chunk_sectors << 9; ··· 4839 4835 static struct md_sysfs_entry md_metadata = 4840 4836 __ATTR_PREALLOC(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store); 4841 4837 4838 + static bool rdev_needs_recovery(struct md_rdev *rdev, sector_t sectors) 4839 + { 4840 + return rdev->raid_disk >= 0 && 4841 + !test_bit(Journal, &rdev->flags) && 4842 + !test_bit(Faulty, &rdev->flags) && 4843 + !test_bit(In_sync, &rdev->flags) && 4844 + rdev->recovery_offset < sectors; 4845 + } 4846 + 4847 + static enum sync_action md_get_active_sync_action(struct mddev *mddev) 4848 + { 4849 + struct md_rdev *rdev; 4850 + bool is_recover = false; 4851 + 4852 + if (mddev->resync_offset < MaxSector) 4853 + return ACTION_RESYNC; 4854 + 4855 + if (mddev->reshape_position != MaxSector) 4856 + return ACTION_RESHAPE; 4857 + 4858 + rcu_read_lock(); 4859 + rdev_for_each_rcu(rdev, mddev) { 4860 + if (rdev_needs_recovery(rdev, MaxSector)) { 4861 + is_recover = true; 4862 + break; 4863 + } 4864 + } 4865 + rcu_read_unlock(); 4866 + 4867 + return is_recover ? ACTION_RECOVER : ACTION_IDLE; 4868 + } 4869 + 4842 4870 enum sync_action md_sync_action(struct mddev *mddev) 4843 4871 { 4844 4872 unsigned long recovery = mddev->recovery; 4873 + enum sync_action active_action; 4845 4874 4846 4875 /* 4847 4876 * frozen has the highest priority, means running sync_thread will be ··· 4898 4861 !test_bit(MD_RECOVERY_NEEDED, &recovery)) 4899 4862 return ACTION_IDLE; 4900 4863 4901 - if (test_bit(MD_RECOVERY_RESHAPE, &recovery) || 4902 - mddev->reshape_position != MaxSector) 4864 + /* 4865 + * Check if any sync operation (resync/recover/reshape) is 4866 + * currently active. This ensures that only one sync operation 4867 + * can run at a time. Returns the type of active operation, or 4868 + * ACTION_IDLE if none are active. 4869 + */ 4870 + active_action = md_get_active_sync_action(mddev); 4871 + if (active_action != ACTION_IDLE) 4872 + return active_action; 4873 + 4874 + if (test_bit(MD_RECOVERY_RESHAPE, &recovery)) 4903 4875 return ACTION_RESHAPE; 4904 4876 4905 4877 if (test_bit(MD_RECOVERY_RECOVER, &recovery)) ··· 5864 5818 { 5865 5819 struct mddev *mddev = container_of(ko, struct mddev, kobj); 5866 5820 5821 + if (legacy_async_del_gendisk) { 5822 + if (mddev->sysfs_state) 5823 + sysfs_put(mddev->sysfs_state); 5824 + if (mddev->sysfs_level) 5825 + sysfs_put(mddev->sysfs_level); 5826 + del_gendisk(mddev->gendisk); 5827 + } 5867 5828 put_disk(mddev->gendisk); 5868 5829 } 5869 5830 ··· 6073 6020 static int md_alloc_and_put(dev_t dev, char *name) 6074 6021 { 6075 6022 struct mddev *mddev = md_alloc(dev, name); 6023 + 6024 + if (legacy_async_del_gendisk) 6025 + pr_warn("md: async del_gendisk mode will be removed in future, please upgrade to mdadm-4.5+\n"); 6076 6026 6077 6027 if (IS_ERR(mddev)) 6078 6028 return PTR_ERR(mddev); ··· 6487 6431 mddev->persistent = 0; 6488 6432 mddev->level = LEVEL_NONE; 6489 6433 mddev->clevel[0] = 0; 6490 - /* if UNTIL_STOP is set, it's cleared here */ 6491 - mddev->hold_active = 0; 6492 - /* Don't clear MD_CLOSING, or mddev can be opened again. */ 6493 - mddev->flags &= BIT_ULL_MASK(MD_CLOSING); 6434 + 6435 + /* 6436 + * For legacy_async_del_gendisk mode, it can stop the array in the 6437 + * middle of assembling it, then it still can access the array. So 6438 + * it needs to clear MD_CLOSING. If not legacy_async_del_gendisk, 6439 + * it can't open the array again after stopping it. So it doesn't 6440 + * clear MD_CLOSING. 6441 + */ 6442 + if (legacy_async_del_gendisk && mddev->hold_active) { 6443 + clear_bit(MD_CLOSING, &mddev->flags); 6444 + } else { 6445 + /* if UNTIL_STOP is set, it's cleared here */ 6446 + mddev->hold_active = 0; 6447 + /* Don't clear MD_CLOSING, or mddev can be opened again. */ 6448 + mddev->flags &= BIT_ULL_MASK(MD_CLOSING); 6449 + } 6494 6450 mddev->sb_flags = 0; 6495 6451 mddev->ro = MD_RDWR; 6496 6452 mddev->metadata_type[0] = 0; ··· 6726 6658 6727 6659 export_array(mddev); 6728 6660 md_clean(mddev); 6729 - set_bit(MD_DELETED, &mddev->flags); 6661 + if (!legacy_async_del_gendisk) 6662 + set_bit(MD_DELETED, &mddev->flags); 6730 6663 } 6731 6664 md_new_event(); 6732 6665 sysfs_notify_dirent_safe(mddev->sysfs_state); ··· 9037 8968 start = MaxSector; 9038 8969 rcu_read_lock(); 9039 8970 rdev_for_each_rcu(rdev, mddev) 9040 - if (rdev->raid_disk >= 0 && 9041 - !test_bit(Journal, &rdev->flags) && 9042 - !test_bit(Faulty, &rdev->flags) && 9043 - !test_bit(In_sync, &rdev->flags) && 9044 - rdev->recovery_offset < start) 8971 + if (rdev_needs_recovery(rdev, start)) 9045 8972 start = rdev->recovery_offset; 9046 8973 rcu_read_unlock(); 9047 8974 ··· 9396 9331 test_bit(MD_RECOVERY_RECOVER, &mddev->recovery)) { 9397 9332 rcu_read_lock(); 9398 9333 rdev_for_each_rcu(rdev, mddev) 9399 - if (rdev->raid_disk >= 0 && 9400 - mddev->delta_disks >= 0 && 9401 - !test_bit(Journal, &rdev->flags) && 9402 - !test_bit(Faulty, &rdev->flags) && 9403 - !test_bit(In_sync, &rdev->flags) && 9404 - rdev->recovery_offset < mddev->curr_resync) 9334 + if (mddev->delta_disks >= 0 && 9335 + rdev_needs_recovery(rdev, mddev->curr_resync)) 9405 9336 rdev->recovery_offset = mddev->curr_resync; 9406 9337 rcu_read_unlock(); 9407 9338 } ··· 10453 10392 module_param(start_dirty_degraded, int, S_IRUGO|S_IWUSR); 10454 10393 module_param_call(new_array, add_named_array, NULL, NULL, S_IWUSR); 10455 10394 module_param(create_on_open, bool, S_IRUSR|S_IWUSR); 10395 + module_param(legacy_async_del_gendisk, bool, 0600); 10456 10396 10457 10397 MODULE_LICENSE("GPL"); 10458 10398 MODULE_DESCRIPTION("MD RAID framework");
+1 -1
include/uapi/linux/raid/md_p.h
··· 173 173 #else 174 174 #error unspecified endianness 175 175 #endif 176 - __u32 resync_offset; /* 11 resync checkpoint sector count */ 176 + __u32 recovery_cp; /* 11 resync checkpoint sector count */ 177 177 /* There are only valid for minor_version > 90 */ 178 178 __u64 reshape_position; /* 12,13 next address in array-space for reshape */ 179 179 __u32 new_level; /* 14 new level we are reshaping to */