Skip to content

Commit 48df498

Browse files
GuoqingJiangshligit
authored andcommitted
md: move bitmap_destroy to the beginning of __md_stop
Since we have switched to sync way to handle METADATA_UPDATED msg for md-cluster, then process_metadata_update is depended on mddev->thread->wqueue. With the new change, clustered raid could possible hang if array received a METADATA_UPDATED msg after array unregistered mddev->thread, so we need to stop clustered raid (bitmap_destroy -> bitmap_free -> md_cluster_stop) earlier than unregister thread (mddev_detach -> md_unregister_thread). And this change should be safe for non-clustered raid since all writes are stopped before the destroy. Also in md_run, we activate the personality (pers->run()) before activating the bitmap (bitmap_create()). So it is pleasingly symmetric to stop the bitmap (bitmap_destroy()) before stopping the personality (__md_stop() calls pers->free()), we achieve this by move bitmap_destroy to the beginning of __md_stop. But we don't want to break the codes for waiting behind IO as Shaohua mentioned, so introduce bitmap_wait_behind_writes to call the codes, and call the new fun in both mddev_detach and bitmap_destroy, then we will not break original behind IO code and also fit the new condition well. Signed-off-by: Guoqing Jiang <[email protected]> Signed-off-by: Shaohua Li <[email protected]>
1 parent ea17481 commit 48df498

File tree

3 files changed

+19
-11
lines changed

3 files changed

+19
-11
lines changed

drivers/md/bitmap.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,13 +1764,29 @@ void bitmap_free(struct bitmap *bitmap)
17641764
}
17651765
EXPORT_SYMBOL(bitmap_free);
17661766

1767+
void bitmap_wait_behind_writes(struct mddev *mddev)
1768+
{
1769+
struct bitmap *bitmap = mddev->bitmap;
1770+
1771+
/* wait for behind writes to complete */
1772+
if (bitmap && atomic_read(&bitmap->behind_writes) > 0) {
1773+
pr_debug("md:%s: behind writes in progress - waiting to stop.\n",
1774+
mdname(mddev));
1775+
/* need to kick something here to make sure I/O goes? */
1776+
wait_event(bitmap->behind_wait,
1777+
atomic_read(&bitmap->behind_writes) == 0);
1778+
}
1779+
}
1780+
17671781
void bitmap_destroy(struct mddev *mddev)
17681782
{
17691783
struct bitmap *bitmap = mddev->bitmap;
17701784

17711785
if (!bitmap) /* there was no bitmap */
17721786
return;
17731787

1788+
bitmap_wait_behind_writes(mddev);
1789+
17741790
mutex_lock(&mddev->bitmap_info.mutex);
17751791
spin_lock(&mddev->lock);
17761792
mddev->bitmap = NULL; /* disconnect from the md device */

drivers/md/bitmap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot);
271271
int bitmap_copy_from_slot(struct mddev *mddev, int slot,
272272
sector_t *lo, sector_t *hi, bool clear_bits);
273273
void bitmap_free(struct bitmap *bitmap);
274+
void bitmap_wait_behind_writes(struct mddev *mddev);
274275
#endif
275276

276277
#endif

drivers/md/md.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5675,15 +5675,7 @@ EXPORT_SYMBOL_GPL(md_stop_writes);
56755675

56765676
static void mddev_detach(struct mddev *mddev)
56775677
{
5678-
struct bitmap *bitmap = mddev->bitmap;
5679-
/* wait for behind writes to complete */
5680-
if (bitmap && atomic_read(&bitmap->behind_writes) > 0) {
5681-
pr_debug("md:%s: behind writes in progress - waiting to stop.\n",
5682-
mdname(mddev));
5683-
/* need to kick something here to make sure I/O goes? */
5684-
wait_event(bitmap->behind_wait,
5685-
atomic_read(&bitmap->behind_writes) == 0);
5686-
}
5678+
bitmap_wait_behind_writes(mddev);
56875679
if (mddev->pers && mddev->pers->quiesce) {
56885680
mddev->pers->quiesce(mddev, 1);
56895681
mddev->pers->quiesce(mddev, 0);
@@ -5696,6 +5688,7 @@ static void mddev_detach(struct mddev *mddev)
56965688
static void __md_stop(struct mddev *mddev)
56975689
{
56985690
struct md_personality *pers = mddev->pers;
5691+
bitmap_destroy(mddev);
56995692
mddev_detach(mddev);
57005693
/* Ensure ->event_work is done */
57015694
flush_workqueue(md_misc_wq);
@@ -5716,7 +5709,6 @@ void md_stop(struct mddev *mddev)
57165709
* This is called from dm-raid
57175710
*/
57185711
__md_stop(mddev);
5719-
bitmap_destroy(mddev);
57205712
if (mddev->bio_set)
57215713
bioset_free(mddev->bio_set);
57225714
}
@@ -5854,7 +5846,6 @@ static int do_md_stop(struct mddev *mddev, int mode,
58545846
if (mode == 0) {
58555847
pr_info("md: %s stopped.\n", mdname(mddev));
58565848

5857-
bitmap_destroy(mddev);
58585849
if (mddev->bitmap_info.file) {
58595850
struct file *f = mddev->bitmap_info.file;
58605851
spin_lock(&mddev->lock);

0 commit comments

Comments
 (0)