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.

md/md-bitmap: add a none backend for bitmap grow

Add a real none bitmap backend that exposes the common bitmap sysfs
group and use it to keep bitmap/location available when an array has no
bitmap.

Then switch the bitmap location sysfs path to move only between none
and the classic bitmap backend, using the no-sysfs bitmap helpers while
merging or unmerging the internal bitmap sysfs group.

This restores mdadm --grow bitmap addition through bitmap/location.

Fixes: fb8cc3b0d9db ("md/md-bitmap: delay registration of bitmap_ops until creating bitmap")
Reviewed-by: Su Yue <glass.su@suse.com>
Link: https://lore.kernel.org/r/20260425024615.1696892-4-yukuai@fnnas.com
Signed-off-by: Yu Kuai <yukuai@fnnas.com>

+138 -17
+101 -9
drivers/md/md-bitmap.c
··· 216 216 }; 217 217 218 218 static struct workqueue_struct *md_bitmap_wq; 219 + static struct attribute_group md_bitmap_internal_group; 219 220 220 221 static int __bitmap_resize(struct bitmap *bitmap, sector_t blocks, 221 222 int chunksize, bool init); ··· 2581 2580 return __bitmap_resize(bitmap, blocks, chunksize, false); 2582 2581 } 2583 2582 2583 + static bool bitmap_none_enabled(void *data, bool flush) 2584 + { 2585 + return false; 2586 + } 2587 + 2588 + static int bitmap_none_create(struct mddev *mddev) 2589 + { 2590 + return 0; 2591 + } 2592 + 2593 + static int bitmap_none_load(struct mddev *mddev) 2594 + { 2595 + return 0; 2596 + } 2597 + 2598 + static void bitmap_none_destroy(struct mddev *mddev) 2599 + { 2600 + } 2601 + 2602 + static int bitmap_none_get_stats(void *data, struct md_bitmap_stats *stats) 2603 + { 2604 + return -ENOENT; 2605 + } 2606 + 2584 2607 static ssize_t 2585 2608 location_show(struct mddev *mddev, char *page) 2586 2609 { ··· 2643 2618 goto out; 2644 2619 } 2645 2620 2646 - bitmap_destroy(mddev); 2621 + sysfs_unmerge_group(&mddev->kobj, &md_bitmap_internal_group); 2622 + md_bitmap_destroy_nosysfs(mddev); 2623 + mddev->bitmap_id = ID_BITMAP_NONE; 2624 + if (!mddev_set_bitmap_ops_nosysfs(mddev)) 2625 + goto none_err; 2647 2626 mddev->bitmap_info.offset = 0; 2648 2627 if (mddev->bitmap_info.file) { 2649 2628 struct file *f = mddev->bitmap_info.file; ··· 2683 2654 } 2684 2655 2685 2656 mddev->bitmap_info.offset = offset; 2686 - rv = bitmap_create(mddev); 2687 - if (rv) 2688 - goto out; 2657 + md_bitmap_destroy_nosysfs(mddev); 2658 + mddev->bitmap_id = ID_BITMAP; 2659 + if (!mddev_set_bitmap_ops_nosysfs(mddev)) 2660 + goto bitmap_err; 2689 2661 2690 - rv = bitmap_load(mddev); 2662 + rv = md_bitmap_create_nosysfs(mddev); 2663 + if (rv) 2664 + goto create_err; 2665 + 2666 + rv = mddev->bitmap_ops->load(mddev); 2691 2667 if (rv) { 2692 2668 mddev->bitmap_info.offset = 0; 2693 - bitmap_destroy(mddev); 2694 - goto out; 2669 + goto load_err; 2695 2670 } 2671 + 2672 + rv = sysfs_merge_group(&mddev->kobj, 2673 + &md_bitmap_internal_group); 2674 + if (rv) 2675 + goto merge_err; 2696 2676 } 2697 2677 } 2698 2678 if (!mddev->external) { ··· 2717 2679 if (rv) 2718 2680 return rv; 2719 2681 return len; 2682 + 2683 + merge_err: 2684 + mddev->bitmap_info.offset = 0; 2685 + load_err: 2686 + md_bitmap_destroy_nosysfs(mddev); 2687 + create_err: 2688 + mddev->bitmap_info.offset = 0; 2689 + mddev->bitmap_id = ID_BITMAP_NONE; 2690 + if (!mddev_set_bitmap_ops_nosysfs(mddev)) 2691 + rv = -ENOENT; 2692 + goto out; 2693 + bitmap_err: 2694 + rv = -ENOENT; 2695 + none_err: 2696 + mddev->bitmap_info.offset = 0; 2697 + goto out; 2720 2698 } 2721 2699 2722 2700 static struct md_sysfs_entry bitmap_location = ··· 3041 2987 NULL, 3042 2988 }; 3043 2989 2990 + static const struct attribute_group *bitmap_none_groups[] = { 2991 + &md_bitmap_common_group, 2992 + NULL, 2993 + }; 2994 + 2995 + static struct bitmap_operations bitmap_none_ops = { 2996 + .head = { 2997 + .type = MD_BITMAP, 2998 + .id = ID_BITMAP_NONE, 2999 + .name = "none", 3000 + }, 3001 + 3002 + .enabled = bitmap_none_enabled, 3003 + .create = bitmap_none_create, 3004 + .load = bitmap_none_load, 3005 + .destroy = bitmap_none_destroy, 3006 + .get_stats = bitmap_none_get_stats, 3007 + 3008 + .groups = bitmap_none_groups, 3009 + }; 3010 + 3044 3011 static struct bitmap_operations bitmap_ops = { 3045 3012 .head = { 3046 3013 .type = MD_BITMAP, ··· 3108 3033 3109 3034 int md_bitmap_init(void) 3110 3035 { 3036 + int err; 3037 + 3111 3038 md_bitmap_wq = alloc_workqueue("md_bitmap", WQ_MEM_RECLAIM | WQ_UNBOUND, 3112 3039 0); 3113 3040 if (!md_bitmap_wq) 3114 3041 return -ENOMEM; 3115 3042 3116 - return register_md_submodule(&bitmap_ops.head); 3043 + err = register_md_submodule(&bitmap_none_ops.head); 3044 + if (err) 3045 + goto err_wq; 3046 + 3047 + err = register_md_submodule(&bitmap_ops.head); 3048 + if (err) 3049 + goto err_none; 3050 + 3051 + return 0; 3052 + 3053 + err_none: 3054 + unregister_md_submodule(&bitmap_none_ops.head); 3055 + err_wq: 3056 + destroy_workqueue(md_bitmap_wq); 3057 + return err; 3117 3058 } 3118 3059 3119 3060 void md_bitmap_exit(void) 3120 3061 { 3121 - destroy_workqueue(md_bitmap_wq); 3122 3062 unregister_md_submodule(&bitmap_ops.head); 3063 + unregister_md_submodule(&bitmap_none_ops.head); 3064 + destroy_workqueue(md_bitmap_wq); 3123 3065 }
+34 -8
drivers/md/md.c
··· 705 705 sysfs_remove_group(&mddev->kobj, mddev->bitmap_ops->groups[0]); 706 706 } 707 707 708 - static bool mddev_set_bitmap_ops_nosysfs(struct mddev *mddev) 708 + bool mddev_set_bitmap_ops_nosysfs(struct mddev *mddev) 709 709 { 710 710 struct md_submodule_head *head; 711 711 ··· 4275 4275 4276 4276 xa_lock(&md_submodule); 4277 4277 xa_for_each(&md_submodule, i, head) { 4278 - if (head->type != MD_BITMAP) 4278 + if (head->type != MD_BITMAP || head->id == ID_BITMAP_NONE) 4279 4279 continue; 4280 4280 4281 4281 if (mddev->bitmap_id == head->id) ··· 6535 6535 return id; 6536 6536 } 6537 6537 6538 - static int md_bitmap_create_nosysfs(struct mddev *mddev) 6538 + int md_bitmap_create_nosysfs(struct mddev *mddev) 6539 6539 { 6540 6540 enum md_submodule_id orig_id = mddev->bitmap_id; 6541 6541 enum md_submodule_id sb_id; ··· 6544 6544 if (mddev->bitmap_id == ID_BITMAP_NONE) 6545 6545 return -EINVAL; 6546 6546 6547 - if (!mddev_set_bitmap_ops_nosysfs(mddev)) 6547 + if (!mddev_set_bitmap_ops_nosysfs(mddev)) { 6548 + mddev->bitmap_id = orig_id; 6548 6549 return -ENOENT; 6550 + } 6549 6551 6550 6552 err = mddev->bitmap_ops->create(mddev); 6551 6553 if (!err) ··· 6561 6559 mddev->bitmap_ops = NULL; 6562 6560 6563 6561 sb_id = md_bitmap_get_id_from_sb(mddev); 6564 - if (sb_id == ID_BITMAP_NONE || sb_id == orig_id) 6562 + if (sb_id == ID_BITMAP_NONE || sb_id == orig_id) { 6563 + mddev->bitmap_id = orig_id; 6565 6564 return err; 6565 + } 6566 6566 6567 6567 pr_info("md: %s: bitmap version mismatch, switching from %d to %d\n", 6568 6568 mdname(mddev), orig_id, sb_id); ··· 6598 6594 return 0; 6599 6595 } 6600 6596 6601 - static void md_bitmap_destroy_nosysfs(struct mddev *mddev) 6597 + void md_bitmap_destroy_nosysfs(struct mddev *mddev) 6602 6598 { 6603 6599 if (!md_bitmap_registered(mddev)) 6604 6600 return; ··· 6614 6610 md_bitmap_sysfs_del(mddev); 6615 6611 6616 6612 md_bitmap_destroy_nosysfs(mddev); 6613 + } 6614 + 6615 + static void md_bitmap_set_none(struct mddev *mddev) 6616 + { 6617 + mddev->bitmap_id = ID_BITMAP_NONE; 6618 + if (!mddev_set_bitmap_ops_nosysfs(mddev)) 6619 + return; 6620 + 6621 + if (!mddev_is_dm(mddev) && mddev->bitmap_ops->groups) 6622 + md_bitmap_sysfs_add(mddev); 6617 6623 } 6618 6624 6619 6625 int md_run(struct mddev *mddev) ··· 6834 6820 6835 6821 if (mddev->sb_flags) 6836 6822 md_update_sb(mddev, 0); 6823 + 6824 + if (IS_ENABLED(CONFIG_MD_BITMAP) && !mddev->bitmap_info.file && 6825 + !mddev->bitmap_info.offset) 6826 + md_bitmap_set_none(mddev); 6837 6827 6838 6828 md_new_event(); 6839 6829 return 0; ··· 7784 7766 { 7785 7767 int err = 0; 7786 7768 7787 - if (!md_bitmap_registered(mddev)) 7769 + if (!md_bitmap_registered(mddev) || 7770 + mddev->bitmap_id == ID_BITMAP_NONE) 7788 7771 return -EINVAL; 7789 7772 7790 7773 if (mddev->pers) { ··· 7850 7831 7851 7832 if (err) { 7852 7833 md_bitmap_destroy(mddev); 7834 + md_bitmap_set_none(mddev); 7853 7835 fd = -1; 7854 7836 } 7855 7837 } else if (fd < 0) { 7856 7838 md_bitmap_destroy(mddev); 7839 + md_bitmap_set_none(mddev); 7857 7840 } 7858 7841 } 7859 7842 ··· 8162 8141 mddev->bitmap_info.default_offset; 8163 8142 mddev->bitmap_info.space = 8164 8143 mddev->bitmap_info.default_space; 8144 + mddev->bitmap_id = ID_BITMAP; 8165 8145 rv = md_bitmap_create(mddev); 8166 8146 if (!rv) 8167 8147 rv = mddev->bitmap_ops->load(mddev); 8168 8148 8169 - if (rv) 8149 + if (rv) { 8170 8150 md_bitmap_destroy(mddev); 8151 + mddev->bitmap_info.offset = 0; 8152 + md_bitmap_set_none(mddev); 8153 + } 8171 8154 } else { 8172 8155 struct md_bitmap_stats stats; 8173 8156 ··· 8199 8174 } 8200 8175 md_bitmap_destroy(mddev); 8201 8176 mddev->bitmap_info.offset = 0; 8177 + md_bitmap_set_none(mddev); 8202 8178 } 8203 8179 } 8204 8180 md_update_sb(mddev, 1);
+3
drivers/md/md.h
··· 934 934 extern void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev); 935 935 extern void md_set_array_sectors(struct mddev *mddev, sector_t array_sectors); 936 936 extern int md_check_no_bitmap(struct mddev *mddev); 937 + bool mddev_set_bitmap_ops_nosysfs(struct mddev *mddev); 938 + int md_bitmap_create_nosysfs(struct mddev *mddev); 939 + void md_bitmap_destroy_nosysfs(struct mddev *mddev); 937 940 extern int md_integrity_register(struct mddev *mddev); 938 941 extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); 939 942