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

md: switch personalities to use md_submodule_head

Remove the global list 'pers_list', and switch to use md_submodule_head,
which is managed by xarry. Prepare to unify registration and unregistration
for all sub modules.

Link: https://lore.kernel.org/linux-raid/20250215092225.2427977-5-yukuai1@huaweicloud.com
Signed-off-by: Yu Kuai <yukuai3@huawei.com>

authored by

Yu Kuai and committed by
Yu Kuai
3d44e1d1 d3beb7c9

+130 -106
+9 -6
drivers/md/md-linear.c
··· 5 5 */ 6 6 7 7 #include <linux/blkdev.h> 8 - #include <linux/raid/md_u.h> 9 8 #include <linux/seq_file.h> 10 9 #include <linux/module.h> 11 10 #include <linux/slab.h> ··· 319 320 } 320 321 321 322 static struct md_personality linear_personality = { 322 - .name = "linear", 323 - .level = LEVEL_LINEAR, 324 - .owner = THIS_MODULE, 323 + .head = { 324 + .type = MD_PERSONALITY, 325 + .id = ID_LINEAR, 326 + .name = "linear", 327 + .owner = THIS_MODULE, 328 + }, 329 + 325 330 .make_request = linear_make_request, 326 331 .run = linear_run, 327 332 .free = linear_free, ··· 338 335 339 336 static int __init linear_init(void) 340 337 { 341 - return register_md_personality(&linear_personality); 338 + return register_md_submodule(&linear_personality.head); 342 339 } 343 340 344 341 static void linear_exit(void) 345 342 { 346 - unregister_md_personality(&linear_personality); 343 + unregister_md_submodule(&linear_personality.head); 347 344 } 348 345 349 346 module_init(linear_init);
+33 -49
drivers/md/md.c
··· 81 81 82 82 static DEFINE_XARRAY(md_submodule); 83 83 84 - /* pers_list is a list of registered personalities protected by pers_lock. */ 85 - static LIST_HEAD(pers_list); 86 84 static DEFINE_SPINLOCK(pers_lock); 87 85 88 86 static const struct kobj_type md_ktype; ··· 891 893 static struct md_personality *get_pers(int level, char *clevel) 892 894 { 893 895 struct md_personality *ret = NULL; 894 - struct md_personality *pers; 896 + struct md_submodule_head *head; 897 + unsigned long i; 895 898 896 - spin_lock(&pers_lock); 897 - list_for_each_entry(pers, &pers_list, list) { 898 - if ((level != LEVEL_NONE && pers->level == level) || 899 - !strcmp(pers->name, clevel)) { 900 - if (try_module_get(pers->owner)) 901 - ret = pers; 899 + xa_lock(&md_submodule); 900 + xa_for_each(&md_submodule, i, head) { 901 + if (head->type != MD_PERSONALITY) 902 + continue; 903 + if ((level != LEVEL_NONE && head->id == level) || 904 + !strcmp(head->name, clevel)) { 905 + if (try_module_get(head->owner)) 906 + ret = (void *)head; 902 907 break; 903 908 } 904 909 } 905 - spin_unlock(&pers_lock); 910 + xa_unlock(&md_submodule); 906 911 907 912 if (!ret) { 908 913 if (level != LEVEL_NONE) ··· 921 920 922 921 static void put_pers(struct md_personality *pers) 923 922 { 924 - module_put(pers->owner); 923 + module_put(pers->head.owner); 925 924 } 926 925 927 926 /* return the offset of the super block in 512byte sectors */ ··· 1204 1203 if (!mddev->bitmap_info.file && !mddev->bitmap_info.offset) 1205 1204 return 0; 1206 1205 pr_warn("%s: bitmaps are not supported for %s\n", 1207 - mdname(mddev), mddev->pers->name); 1206 + mdname(mddev), mddev->pers->head.name); 1208 1207 return 1; 1209 1208 } 1210 1209 EXPORT_SYMBOL(md_check_no_bitmap); ··· 3884 3883 spin_lock(&mddev->lock); 3885 3884 p = mddev->pers; 3886 3885 if (p) 3887 - ret = sprintf(page, "%s\n", p->name); 3886 + ret = sprintf(page, "%s\n", p->head.name); 3888 3887 else if (mddev->clevel[0]) 3889 3888 ret = sprintf(page, "%s\n", mddev->clevel); 3890 3889 else if (mddev->level != LEVEL_NONE) ··· 3941 3940 rv = -EINVAL; 3942 3941 if (!mddev->pers->quiesce) { 3943 3942 pr_warn("md: %s: %s does not support online personality change\n", 3944 - mdname(mddev), mddev->pers->name); 3943 + mdname(mddev), mddev->pers->head.name); 3945 3944 goto out_unlock; 3946 3945 } 3947 3946 ··· 4004 4003 oldpriv = mddev->private; 4005 4004 mddev->pers = pers; 4006 4005 mddev->private = priv; 4007 - strscpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); 4006 + strscpy(mddev->clevel, pers->head.name, sizeof(mddev->clevel)); 4008 4007 mddev->level = mddev->new_level; 4009 4008 mddev->layout = mddev->new_layout; 4010 4009 mddev->chunk_sectors = mddev->new_chunk_sectors; ··· 5604 5603 5605 5604 static ssize_t serialize_policy_show(struct mddev *mddev, char *page) 5606 5605 { 5607 - if (mddev->pers == NULL || (mddev->pers->level != 1)) 5606 + if (mddev->pers == NULL || (mddev->pers->head.id != ID_RAID1)) 5608 5607 return sprintf(page, "n/a\n"); 5609 5608 else 5610 5609 return sprintf(page, "%d\n", mddev->serialize_policy); ··· 5630 5629 err = mddev_suspend_and_lock(mddev); 5631 5630 if (err) 5632 5631 return err; 5633 - if (mddev->pers == NULL || (mddev->pers->level != 1)) { 5632 + if (mddev->pers == NULL || (mddev->pers->head.id != ID_RAID1)) { 5634 5633 pr_err("md: serialize_policy is only effective for raid1\n"); 5635 5634 err = -EINVAL; 5636 5635 goto unlock; ··· 6121 6120 err = -EINVAL; 6122 6121 goto abort; 6123 6122 } 6124 - if (mddev->level != pers->level) { 6125 - mddev->level = pers->level; 6126 - mddev->new_level = pers->level; 6123 + if (mddev->level != pers->head.id) { 6124 + mddev->level = pers->head.id; 6125 + mddev->new_level = pers->head.id; 6127 6126 } 6128 - strscpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); 6127 + strscpy(mddev->clevel, pers->head.name, sizeof(mddev->clevel)); 6129 6128 6130 6129 if (mddev->reshape_position != MaxSector && 6131 6130 pers->start_reshape == NULL) { ··· 8135 8134 return; 8136 8135 mddev->pers->error_handler(mddev, rdev); 8137 8136 8138 - if (mddev->pers->level == 0 || mddev->pers->level == LEVEL_LINEAR) 8137 + if (mddev->pers->head.id == ID_RAID0 || 8138 + mddev->pers->head.id == ID_LINEAR) 8139 8139 return; 8140 8140 8141 8141 if (mddev->degraded && !test_bit(MD_BROKEN, &mddev->flags)) ··· 8174 8172 8175 8173 static void status_personalities(struct seq_file *seq) 8176 8174 { 8177 - struct md_personality *pers; 8175 + struct md_submodule_head *head; 8176 + unsigned long i; 8178 8177 8179 8178 seq_puts(seq, "Personalities : "); 8180 - spin_lock(&pers_lock); 8181 - list_for_each_entry(pers, &pers_list, list) 8182 - seq_printf(seq, "[%s] ", pers->name); 8183 8179 8184 - spin_unlock(&pers_lock); 8180 + xa_lock(&md_submodule); 8181 + xa_for_each(&md_submodule, i, head) 8182 + if (head->type == MD_PERSONALITY) 8183 + seq_printf(seq, "[%s] ", head->name); 8184 + xa_unlock(&md_submodule); 8185 + 8185 8186 seq_puts(seq, "\n"); 8186 8187 } 8187 8188 ··· 8407 8402 seq_printf(seq, " (read-only)"); 8408 8403 if (mddev->ro == MD_AUTO_READ) 8409 8404 seq_printf(seq, " (auto-read-only)"); 8410 - seq_printf(seq, " %s", mddev->pers->name); 8405 + seq_printf(seq, " %s", mddev->pers->head.name); 8411 8406 } else { 8412 8407 seq_printf(seq, "inactive"); 8413 8408 } ··· 8540 8535 xa_erase(&md_submodule, msh->id); 8541 8536 } 8542 8537 EXPORT_SYMBOL_GPL(unregister_md_submodule); 8543 - 8544 - int register_md_personality(struct md_personality *p) 8545 - { 8546 - pr_debug("md: %s personality registered for level %d\n", 8547 - p->name, p->level); 8548 - spin_lock(&pers_lock); 8549 - list_add_tail(&p->list, &pers_list); 8550 - spin_unlock(&pers_lock); 8551 - return 0; 8552 - } 8553 - EXPORT_SYMBOL(register_md_personality); 8554 - 8555 - int unregister_md_personality(struct md_personality *p) 8556 - { 8557 - pr_debug("md: %s personality unregistered\n", p->name); 8558 - spin_lock(&pers_lock); 8559 - list_del_init(&p->list); 8560 - spin_unlock(&pers_lock); 8561 - return 0; 8562 - } 8563 - EXPORT_SYMBOL(unregister_md_personality); 8564 8538 8565 8539 int register_md_cluster_operations(const struct md_cluster_operations *ops, 8566 8540 struct module *module)
+1 -6
drivers/md/md.h
··· 726 726 struct md_personality 727 727 { 728 728 struct md_submodule_head head; 729 - char *name; 730 - int level; 731 - struct list_head list; 732 - struct module *owner; 729 + 733 730 bool __must_check (*make_request)(struct mddev *mddev, struct bio *bio); 734 731 /* 735 732 * start up works that do NOT require md_thread. tasks that ··· 870 873 int register_md_submodule(struct md_submodule_head *msh); 871 874 void unregister_md_submodule(struct md_submodule_head *msh); 872 875 873 - extern int register_md_personality(struct md_personality *p); 874 - extern int unregister_md_personality(struct md_personality *p); 875 876 extern struct md_thread *md_register_thread( 876 877 void (*run)(struct md_thread *thread), 877 878 struct mddev *mddev,
+11 -7
drivers/md/raid0.c
··· 811 811 812 812 static struct md_personality raid0_personality= 813 813 { 814 - .name = "raid0", 815 - .level = 0, 816 - .owner = THIS_MODULE, 814 + .head = { 815 + .type = MD_PERSONALITY, 816 + .id = ID_RAID0, 817 + .name = "raid0", 818 + .owner = THIS_MODULE, 819 + }, 820 + 817 821 .make_request = raid0_make_request, 818 822 .run = raid0_run, 819 823 .free = raid0_free, ··· 828 824 .error_handler = raid0_error, 829 825 }; 830 826 831 - static int __init raid0_init (void) 827 + static int __init raid0_init(void) 832 828 { 833 - return register_md_personality (&raid0_personality); 829 + return register_md_submodule(&raid0_personality.head); 834 830 } 835 831 836 - static void raid0_exit (void) 832 + static void __exit raid0_exit(void) 837 833 { 838 - unregister_md_personality (&raid0_personality); 834 + unregister_md_submodule(&raid0_personality.head); 839 835 } 840 836 841 837 module_init(raid0_init);
+13 -9
drivers/md/raid1.c
··· 3500 3500 3501 3501 static struct md_personality raid1_personality = 3502 3502 { 3503 - .name = "raid1", 3504 - .level = 1, 3505 - .owner = THIS_MODULE, 3503 + .head = { 3504 + .type = MD_PERSONALITY, 3505 + .id = ID_RAID1, 3506 + .name = "raid1", 3507 + .owner = THIS_MODULE, 3508 + }, 3509 + 3506 3510 .make_request = raid1_make_request, 3507 3511 .run = raid1_run, 3508 3512 .free = raid1_free, ··· 3523 3519 .takeover = raid1_takeover, 3524 3520 }; 3525 3521 3526 - static int __init raid_init(void) 3522 + static int __init raid1_init(void) 3527 3523 { 3528 - return register_md_personality(&raid1_personality); 3524 + return register_md_submodule(&raid1_personality.head); 3529 3525 } 3530 3526 3531 - static void raid_exit(void) 3527 + static void __exit raid1_exit(void) 3532 3528 { 3533 - unregister_md_personality(&raid1_personality); 3529 + unregister_md_submodule(&raid1_personality.head); 3534 3530 } 3535 3531 3536 - module_init(raid_init); 3537 - module_exit(raid_exit); 3532 + module_init(raid1_init); 3533 + module_exit(raid1_exit); 3538 3534 MODULE_LICENSE("GPL"); 3539 3535 MODULE_DESCRIPTION("RAID1 (mirroring) personality for MD"); 3540 3536 MODULE_ALIAS("md-personality-3"); /* RAID1 */
+13 -9
drivers/md/raid10.c
··· 5126 5126 5127 5127 static struct md_personality raid10_personality = 5128 5128 { 5129 - .name = "raid10", 5130 - .level = 10, 5131 - .owner = THIS_MODULE, 5129 + .head = { 5130 + .type = MD_PERSONALITY, 5131 + .id = ID_RAID10, 5132 + .name = "raid10", 5133 + .owner = THIS_MODULE, 5134 + }, 5135 + 5132 5136 .make_request = raid10_make_request, 5133 5137 .run = raid10_run, 5134 5138 .free = raid10_free, ··· 5152 5148 .update_reshape_pos = raid10_update_reshape_pos, 5153 5149 }; 5154 5150 5155 - static int __init raid_init(void) 5151 + static int __init raid10_init(void) 5156 5152 { 5157 - return register_md_personality(&raid10_personality); 5153 + return register_md_submodule(&raid10_personality.head); 5158 5154 } 5159 5155 5160 - static void raid_exit(void) 5156 + static void __exit raid10_exit(void) 5161 5157 { 5162 - unregister_md_personality(&raid10_personality); 5158 + unregister_md_submodule(&raid10_personality.head); 5163 5159 } 5164 5160 5165 - module_init(raid_init); 5166 - module_exit(raid_exit); 5161 + module_init(raid10_init); 5162 + module_exit(raid10_exit); 5167 5163 MODULE_LICENSE("GPL"); 5168 5164 MODULE_DESCRIPTION("RAID10 (striped mirror) personality for MD"); 5169 5165 MODULE_ALIAS("md-personality-9"); /* RAID10 */
+50 -20
drivers/md/raid5.c
··· 8954 8954 8955 8955 static struct md_personality raid6_personality = 8956 8956 { 8957 - .name = "raid6", 8958 - .level = 6, 8959 - .owner = THIS_MODULE, 8957 + .head = { 8958 + .type = MD_PERSONALITY, 8959 + .id = ID_RAID6, 8960 + .name = "raid6", 8961 + .owner = THIS_MODULE, 8962 + }, 8963 + 8960 8964 .make_request = raid5_make_request, 8961 8965 .run = raid5_run, 8962 8966 .start = raid5_start, ··· 8984 8980 }; 8985 8981 static struct md_personality raid5_personality = 8986 8982 { 8987 - .name = "raid5", 8988 - .level = 5, 8989 - .owner = THIS_MODULE, 8983 + .head = { 8984 + .type = MD_PERSONALITY, 8985 + .id = ID_RAID5, 8986 + .name = "raid5", 8987 + .owner = THIS_MODULE, 8988 + }, 8989 + 8990 8990 .make_request = raid5_make_request, 8991 8991 .run = raid5_run, 8992 8992 .start = raid5_start, ··· 9015 9007 9016 9008 static struct md_personality raid4_personality = 9017 9009 { 9018 - .name = "raid4", 9019 - .level = 4, 9020 - .owner = THIS_MODULE, 9010 + .head = { 9011 + .type = MD_PERSONALITY, 9012 + .id = ID_RAID4, 9013 + .name = "raid4", 9014 + .owner = THIS_MODULE, 9015 + }, 9016 + 9021 9017 .make_request = raid5_make_request, 9022 9018 .run = raid5_run, 9023 9019 .start = raid5_start, ··· 9057 9045 "md/raid5:prepare", 9058 9046 raid456_cpu_up_prepare, 9059 9047 raid456_cpu_dead); 9060 - if (ret) { 9061 - destroy_workqueue(raid5_wq); 9062 - return ret; 9063 - } 9064 - register_md_personality(&raid6_personality); 9065 - register_md_personality(&raid5_personality); 9066 - register_md_personality(&raid4_personality); 9048 + if (ret) 9049 + goto err_destroy_wq; 9050 + 9051 + ret = register_md_submodule(&raid6_personality.head); 9052 + if (ret) 9053 + goto err_cpuhp_remove; 9054 + 9055 + ret = register_md_submodule(&raid5_personality.head); 9056 + if (ret) 9057 + goto err_unregister_raid6; 9058 + 9059 + ret = register_md_submodule(&raid4_personality.head); 9060 + if (ret) 9061 + goto err_unregister_raid5; 9062 + 9067 9063 return 0; 9064 + 9065 + err_unregister_raid5: 9066 + unregister_md_submodule(&raid5_personality.head); 9067 + err_unregister_raid6: 9068 + unregister_md_submodule(&raid6_personality.head); 9069 + err_cpuhp_remove: 9070 + cpuhp_remove_multi_state(CPUHP_MD_RAID5_PREPARE); 9071 + err_destroy_wq: 9072 + destroy_workqueue(raid5_wq); 9073 + return ret; 9068 9074 } 9069 9075 9070 - static void raid5_exit(void) 9076 + static void __exit raid5_exit(void) 9071 9077 { 9072 - unregister_md_personality(&raid6_personality); 9073 - unregister_md_personality(&raid5_personality); 9074 - unregister_md_personality(&raid4_personality); 9078 + unregister_md_submodule(&raid6_personality.head); 9079 + unregister_md_submodule(&raid5_personality.head); 9080 + unregister_md_submodule(&raid4_personality.head); 9075 9081 cpuhp_remove_multi_state(CPUHP_MD_RAID5_PREPARE); 9076 9082 destroy_workqueue(raid5_wq); 9077 9083 }