Skip to content

Commit c20413b

Browse files
committed
Merge tag 'md-6.17-20250722' of https://git.kernel.org/pub/scm/linux/kernel/git/mdraid/linux into for-6.17/block
Pull MD updates from Yu: "- call del_gendisk synchronously, from Xiao - cleanup unused variable, from John - cleanup workqueue flags, from Ryo - fix faulty rdev can't be removed during resync, from Qixing" * tag 'md-6.17-20250722' of https://git.kernel.org/pub/scm/linux/kernel/git/mdraid/linux: md/raid10: fix set but not used variable in sync_request_write() md: allow removing faulty rdev during resync md/raid5: unset WQ_CPU_INTENSIVE for raid5 unbound workqueue md: remove/add redundancy group only in level change md: Don't clear MD_CLOSING until mddev is freed md: call del_gendisk in control path
2 parents b8da740 + bc1c2f0 commit c20413b

4 files changed

Lines changed: 68 additions & 36 deletions

File tree

drivers/md/md.c

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -636,9 +636,6 @@ static void __mddev_put(struct mddev *mddev)
636636
mddev->ctime || mddev->hold_active)
637637
return;
638638

639-
/* Array is not configured at all, and not held active, so destroy it */
640-
set_bit(MD_DELETED, &mddev->flags);
641-
642639
/*
643640
* Call queue_work inside the spinlock so that flush_workqueue() after
644641
* mddev_find will succeed in waiting for the work to be done.
@@ -873,6 +870,16 @@ void mddev_unlock(struct mddev *mddev)
873870
kobject_del(&rdev->kobj);
874871
export_rdev(rdev, mddev);
875872
}
873+
874+
/* Call del_gendisk after release reconfig_mutex to avoid
875+
* deadlock (e.g. call del_gendisk under the lock and an
876+
* access to sysfs files waits the lock)
877+
* And MD_DELETED is only used for md raid which is set in
878+
* do_md_stop. dm raid only uses md_stop to stop. So dm raid
879+
* doesn't need to check MD_DELETED when getting reconfig lock
880+
*/
881+
if (test_bit(MD_DELETED, &mddev->flags))
882+
del_gendisk(mddev->gendisk);
876883
}
877884
EXPORT_SYMBOL_GPL(mddev_unlock);
878885

@@ -5774,32 +5781,37 @@ md_attr_store(struct kobject *kobj, struct attribute *attr,
57745781
struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
57755782
struct mddev *mddev = container_of(kobj, struct mddev, kobj);
57765783
ssize_t rv;
5784+
struct kernfs_node *kn = NULL;
57775785

57785786
if (!entry->store)
57795787
return -EIO;
57805788
if (!capable(CAP_SYS_ADMIN))
57815789
return -EACCES;
5790+
5791+
if (entry->store == array_state_store && cmd_match(page, "clear"))
5792+
kn = sysfs_break_active_protection(kobj, attr);
5793+
57825794
spin_lock(&all_mddevs_lock);
57835795
if (!mddev_get(mddev)) {
57845796
spin_unlock(&all_mddevs_lock);
5797+
if (kn)
5798+
sysfs_unbreak_active_protection(kn);
57855799
return -EBUSY;
57865800
}
57875801
spin_unlock(&all_mddevs_lock);
57885802
rv = entry->store(mddev, page, length);
57895803
mddev_put(mddev);
5804+
5805+
if (kn)
5806+
sysfs_unbreak_active_protection(kn);
5807+
57905808
return rv;
57915809
}
57925810

57935811
static void md_kobj_release(struct kobject *ko)
57945812
{
57955813
struct mddev *mddev = container_of(ko, struct mddev, kobj);
57965814

5797-
if (mddev->sysfs_state)
5798-
sysfs_put(mddev->sysfs_state);
5799-
if (mddev->sysfs_level)
5800-
sysfs_put(mddev->sysfs_level);
5801-
5802-
del_gendisk(mddev->gendisk);
58035815
put_disk(mddev->gendisk);
58045816
}
58055817

@@ -6413,15 +6425,10 @@ static void md_clean(struct mddev *mddev)
64136425
mddev->persistent = 0;
64146426
mddev->level = LEVEL_NONE;
64156427
mddev->clevel[0] = 0;
6416-
/*
6417-
* Don't clear MD_CLOSING, or mddev can be opened again.
6418-
* 'hold_active != 0' means mddev is still in the creation
6419-
* process and will be used later.
6420-
*/
6421-
if (mddev->hold_active)
6422-
mddev->flags = 0;
6423-
else
6424-
mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
6428+
/* if UNTIL_STOP is set, it's cleared here */
6429+
mddev->hold_active = 0;
6430+
/* Don't clear MD_CLOSING, or mddev can be opened again. */
6431+
mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
64256432
mddev->sb_flags = 0;
64266433
mddev->ro = MD_RDWR;
64276434
mddev->metadata_type[0] = 0;
@@ -6516,8 +6523,6 @@ static void __md_stop(struct mddev *mddev)
65166523
if (mddev->private)
65176524
pers->free(mddev, mddev->private);
65186525
mddev->private = NULL;
6519-
if (pers->sync_request && mddev->to_remove == NULL)
6520-
mddev->to_remove = &md_redundancy_group;
65216526
put_pers(pers);
65226527
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
65236528

@@ -6646,10 +6651,8 @@ static int do_md_stop(struct mddev *mddev, int mode)
66466651
mddev->bitmap_info.offset = 0;
66476652

66486653
export_array(mddev);
6649-
66506654
md_clean(mddev);
6651-
if (mddev->hold_active == UNTIL_STOP)
6652-
mddev->hold_active = 0;
6655+
set_bit(MD_DELETED, &mddev->flags);
66536656
}
66546657
md_new_event();
66556658
sysfs_notify_dirent_safe(mddev->sysfs_state);
@@ -9456,17 +9459,11 @@ static bool md_spares_need_change(struct mddev *mddev)
94569459
return false;
94579460
}
94589461

9459-
static int remove_and_add_spares(struct mddev *mddev,
9460-
struct md_rdev *this)
9462+
static int remove_spares(struct mddev *mddev, struct md_rdev *this)
94619463
{
94629464
struct md_rdev *rdev;
9463-
int spares = 0;
94649465
int removed = 0;
94659466

9466-
if (this && test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
9467-
/* Mustn't remove devices when resync thread is running */
9468-
return 0;
9469-
94709467
rdev_for_each(rdev, mddev) {
94719468
if ((this == NULL || rdev == this) && rdev_removeable(rdev) &&
94729469
!mddev->pers->hot_remove_disk(mddev, rdev)) {
@@ -9480,6 +9477,21 @@ static int remove_and_add_spares(struct mddev *mddev,
94809477
if (removed && mddev->kobj.sd)
94819478
sysfs_notify_dirent_safe(mddev->sysfs_degraded);
94829479

9480+
return removed;
9481+
}
9482+
9483+
static int remove_and_add_spares(struct mddev *mddev,
9484+
struct md_rdev *this)
9485+
{
9486+
struct md_rdev *rdev;
9487+
int spares = 0;
9488+
int removed = 0;
9489+
9490+
if (this && test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
9491+
/* Mustn't remove devices when resync thread is running */
9492+
return 0;
9493+
9494+
removed = remove_spares(mddev, this);
94839495
if (this && removed)
94849496
goto no_add;
94859497

@@ -9522,6 +9534,7 @@ static bool md_choose_sync_action(struct mddev *mddev, int *spares)
95229534

95239535
/* Check if resync is in progress. */
95249536
if (mddev->recovery_cp < MaxSector) {
9537+
remove_spares(mddev, NULL);
95259538
set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
95269539
clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
95279540
return true;

drivers/md/md.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,11 +700,26 @@ static inline bool reshape_interrupted(struct mddev *mddev)
700700

701701
static inline int __must_check mddev_lock(struct mddev *mddev)
702702
{
703-
return mutex_lock_interruptible(&mddev->reconfig_mutex);
703+
int ret;
704+
705+
ret = mutex_lock_interruptible(&mddev->reconfig_mutex);
706+
707+
/* MD_DELETED is set in do_md_stop with reconfig_mutex.
708+
* So check it here.
709+
*/
710+
if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
711+
ret = -ENODEV;
712+
mutex_unlock(&mddev->reconfig_mutex);
713+
}
714+
715+
return ret;
704716
}
705717

706718
/* Sometimes we need to take the lock in a situation where
707719
* failure due to interrupts is not acceptable.
720+
* It doesn't need to check MD_DELETED here, the owner which
721+
* holds the lock here can't be stopped. And all paths can't
722+
* call this function after do_md_stop.
708723
*/
709724
static inline void mddev_lock_nointr(struct mddev *mddev)
710725
{
@@ -713,7 +728,14 @@ static inline void mddev_lock_nointr(struct mddev *mddev)
713728

714729
static inline int mddev_trylock(struct mddev *mddev)
715730
{
716-
return mutex_trylock(&mddev->reconfig_mutex);
731+
int ret;
732+
733+
ret = mutex_trylock(&mddev->reconfig_mutex);
734+
if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
735+
ret = -ENODEV;
736+
mutex_unlock(&mddev->reconfig_mutex);
737+
}
738+
return ret;
717739
}
718740
extern void mddev_unlock(struct mddev *mddev);
719741

drivers/md/raid10.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,15 +2438,12 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
24382438
* that are active
24392439
*/
24402440
for (i = 0; i < conf->copies; i++) {
2441-
int d;
2442-
24432441
tbio = r10_bio->devs[i].repl_bio;
24442442
if (!tbio || !tbio->bi_end_io)
24452443
continue;
24462444
if (r10_bio->devs[i].bio->bi_end_io != end_sync_write
24472445
&& r10_bio->devs[i].bio != fbio)
24482446
bio_copy_data(tbio, fbio);
2449-
d = r10_bio->devs[i].devnum;
24502447
atomic_inc(&r10_bio->remaining);
24512448
submit_bio_noacct(tbio);
24522449
}

drivers/md/raid5.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9040,7 +9040,7 @@ static int __init raid5_init(void)
90409040
int ret;
90419041

90429042
raid5_wq = alloc_workqueue("raid5wq",
9043-
WQ_UNBOUND|WQ_MEM_RECLAIM|WQ_CPU_INTENSIVE|WQ_SYSFS, 0);
9043+
WQ_UNBOUND|WQ_MEM_RECLAIM|WQ_SYSFS, 0);
90449044
if (!raid5_wq)
90459045
return -ENOMEM;
90469046

0 commit comments

Comments
 (0)