On Wed, May 7, 2025 at 2:21 PM Yu Kuai <yukuai1@xxxxxxxxxxxxxxx> wrote: > > Hi, > > 在 2025/05/07 10:14, Xiao Ni 写道: > > Before commit 12a6caf27324 ("md: only delete entries from all_mddevs when > > the disk is freed") MD_CLOSING is cleared in ioctl path. Now MD_CLOSING > > will keep until mddev is freed. So MD_CLOSING can be used to check if the > > array is stopping. > > > > Signed-off-by: Xiao Ni <xni@xxxxxxxxxx> > > --- > > drivers/md/md.c | 9 +++------ > > drivers/md/md.h | 2 -- > > 2 files changed, 3 insertions(+), 8 deletions(-) > > > > diff --git a/drivers/md/md.c b/drivers/md/md.c > > index 9b9950ed6ee9..c226747be9e3 100644 > > --- a/drivers/md/md.c > > +++ b/drivers/md/md.c > > @@ -599,7 +599,7 @@ static inline struct mddev *mddev_get(struct mddev *mddev) > > { > > lockdep_assert_held(&all_mddevs_lock); > > > > - if (test_bit(MD_DELETED, &mddev->flags)) > > + if (test_bit(MD_CLOSING, &mddev->flags)) > > return NULL; > > atomic_inc(&mddev->active); > > return mddev; > > I noticed that MD_CLOSING can be set temporarily in following case: > > sysfs: > if (st == readonly || st == read_auto || st == inactive || > ┊ (err && st == clear)) > clear_bit(MD_CLOSING, &mddev->flags); > > ioctl: > if (cmd == STOP_ARRAY_RO || (err && cmd == STOP_ARRAY)) > clear_bit(MD_CLOSING, &mddev->flags); > > > And we should still allow mmdev_get() to pass in these cases. The two places clear MD_CLOSING rather than setting MD_CLOSING. MD_CLOSING is set when we really want to stop the array (STOP_ARRAY cmd and clear>array_state_store). So the two places clear MD_CLOSING for other situations which look good to me. Regards Xiao > > Thanks, > Kuai > > > @@ -613,9 +613,6 @@ static void __mddev_put(struct mddev *mddev) > > mddev->ctime || mddev->hold_active) > > return; > > > > - /* Array is not configured at all, and not held active, so destroy it */ > > - set_bit(MD_DELETED, &mddev->flags); > > - > > /* > > * Call queue_work inside the spinlock so that flush_workqueue() after > > * mddev_find will succeed in waiting for the work to be done. > > @@ -3312,7 +3309,7 @@ static bool md_rdev_overlaps(struct md_rdev *rdev) > > > > spin_lock(&all_mddevs_lock); > > list_for_each_entry(mddev, &all_mddevs, all_mddevs) { > > - if (test_bit(MD_DELETED, &mddev->flags)) > > + if (test_bit(MD_CLOSING, &mddev->flags)) > > continue; > > rdev_for_each(rdev2, mddev) { > > if (rdev != rdev2 && rdev->bdev == rdev2->bdev && > > @@ -8992,7 +8989,7 @@ void md_do_sync(struct md_thread *thread) > > goto skip; > > spin_lock(&all_mddevs_lock); > > list_for_each_entry(mddev2, &all_mddevs, all_mddevs) { > > - if (test_bit(MD_DELETED, &mddev2->flags)) > > + if (test_bit(MD_CLOSING, &mddev2->flags)) > > continue; > > if (mddev2 == mddev) > > continue; > > diff --git a/drivers/md/md.h b/drivers/md/md.h > > index 1cf00a04bcdd..a9dccb3d84ed 100644 > > --- a/drivers/md/md.h > > +++ b/drivers/md/md.h > > @@ -338,7 +338,6 @@ struct md_cluster_operations; > > * @MD_NOT_READY: do_md_run() is active, so 'array_state', ust not report that > > * array is ready yet. > > * @MD_BROKEN: This is used to stop writes and mark array as failed. > > - * @MD_DELETED: This device is being deleted > > * > > * change UNSUPPORTED_MDDEV_FLAGS for each array type if new flag is added > > */ > > @@ -353,7 +352,6 @@ enum mddev_flags { > > MD_HAS_MULTIPLE_PPLS, > > MD_NOT_READY, > > MD_BROKEN, > > - MD_DELETED, > > }; > > > > enum mddev_sb_flags { > > >