md: fix mddev->flags issues
Subsystems (2)
cover md: fix mddev->flags issues
We had some places the mddev->flags are abused. Today I hit a reshape hang, which is related to this issue.
Neil,
I will appreciate if you could review the patches before the merge window start.
Thanks,
Shaohua
Shaohua Li (3):
md: takeover should clear unrelated bits
md: MD_RECOVERY_NEEDED is set for mddev->recovery
md: separate flags for superblock changes
drivers/md/bitmap.c | 4 +- drivers/md/dm-raid.c | 4 +- drivers/md/md.c | 117 ++++++++++++++++++++++++----------------------- drivers/md/md.h | 16 ++++--- drivers/md/multipath.c | 2 +- drivers/md/raid0.c | 5 ++ drivers/md/raid1.c | 17 ++++--- drivers/md/raid10.c | 22 ++++----- drivers/md/raid5-cache.c | 6 +-- drivers/md/raid5.c | 32 +++++++------ 10 files changed, 121 insertions(+), 104 deletions(-)
Signature · 1 line
2.9.3
PATCH 1/3 md: takeover should clear unrelated bits
When we change level from raid1 to raid5, the MD_FAILFAST_SUPPORTED bit will be accidentally set, but raid5 doesn't support it. The same is true for the MD_HAS_JOURNAL bit.
Fix: 46533ff (md: Use REQ_FAILFAST_* on metadata writes where appropriate)
--- drivers/md/raid0.c | 5 +++++ drivers/md/raid1.c | 5 ++++- drivers/md/raid5.c | 6 +++++- 3 files changed, 14 insertions(+), 2 deletions(-)
drivers/md/raid0.c +5 -0
@@ -539,8 +539,11 @@ static void *raid0_takeover_raid45(struct mddev *mddev) mddev->delta_disks =-1 ;/* make sure it will be not marked as dirty */ mddev->recovery_cp = MaxSector; +clear_bit (MD_HAS_JOURNAL , &mddev->flags); +clear_bit (MD_JOURNAL_CLEAN , &mddev->flags);create_strip_zones (mddev, &priv_conf); +return priv_conf; }
@@ -580,6 +583,7 @@ static void *raid0_takeover_raid10(struct mddev *mddev) mddev->degraded =0 ;/* make sure it will be not marked as dirty */ mddev->recovery_cp = MaxSector; +clear_bit (MD_FAILFAST_SUPPORTED , &mddev->flags);create_strip_zones (mddev, &priv_conf);return priv_conf;
@@ -622,6 +626,7 @@ static void *raid0_takeover_raid1(struct mddev *mddev) mddev->raid_disks =1 ;/* make sure it will be not marked as dirty */ mddev->recovery_cp = MaxSector; +clear_bit (MD_FAILFAST_SUPPORTED , &mddev->flags);create_strip_zones (mddev, &priv_conf);return priv_conf;
drivers/md/raid1.c +4 -1
@@ -3243,9 +3243,12 @@ static void *raid1_takeover(struct mddev *mddev) mddev->new_layout =0 ; mddev->new_chunk_sectors =0 ; conf =setup_conf (mddev); -if (!IS_ERR (conf)) +if (!IS_ERR (conf)) {/* Array must appear to be quiesced */ conf->array_frozen =1 ; +clear_bit (MD_HAS_JOURNAL , &mddev->flags); +clear_bit (MD_JOURNAL_CLEAN , &mddev->flags); + }return conf; }return ERR_PTR (-EINVAL );
drivers/md/raid5.c +5 -1
@@ -7811,6 +7811,7 @@ static void *raid45_takeover_raid0(struct mddev *mddev, int level)static void *raid5_takeover_raid1 (struct mddev *mddev) {int chunksect; +void *ret;if (mddev->raid_disks !=2 || mddev->degraded >1 )
@@ -7832,7 +7833,10 @@ static void *raid5_takeover_raid1(struct mddev *mddev) mddev->new_layout =ALGORITHM_LEFT_SYMMETRIC ; mddev->new_chunk_sectors = chunksect; -return setup_conf (mddev); + ret =setup_conf (mddev); +if (!IS_ERR_VALUE (ret)) +clear_bit (MD_FAILFAST_SUPPORTED , &mddev->flags); +return ret; }static void *raid5_takeover_raid6 (struct mddev *mddev)
Signature · 1 line
2.9.3
Re: [PATCH 1/3] md: takeover should clear unrelated bits
Quoted 18 lines · Shaohua Li
When we change level from raid1 to raid5, the
MD_FAILFAST_SUPPORTEDbit will be accidentally set, but raid5 doesn't support it. The same is true for theMD_HAS_JOURNALbit.Fix: 46533ff (md: Use REQ_FAILFAST_* on metadata writes where appropriate)
Cc NeilBrown <[email protected]>Signed-off-by Shaohua Li <[email protected]>--- drivers/md/raid0.c | 5 +++++ drivers/md/raid1.c | 5 ++++- drivers/md/raid5.c | 6 +++++- 3 files changed, 14 insertions(+), 2 deletions(-)drivers/md/raid0.c +0
-0
drivers/md/raid0.c static void *raid0_takeover_raid45(struct mddev *mddev) · line 548
Quoted 10 lines
drivers/md/raid0.c +3
-0@@ -539,8 +539,11 @@ static void *raid0_takeover_raid45(struct mddev *mddev) mddev->delta_disks =-1 ;/* make sure it will be not marked as dirty */ mddev->recovery_cp = MaxSector; +clear_bit (MD_HAS_JOURNAL , &mddev->flags); +clear_bit (MD_JOURNAL_CLEAN , &mddev->flags);create_strip_zones (mddev, &priv_conf); +return priv_conf; }
This looks like a good fix, but it is a little fragile. If a new bit is added, we would need to go through all the takeover functions and check if it needs to be cleared, and we would forget. It might be better if each personality defined a VALID_MD_FLAGS or whatever, and the takeover function always did
set_mask_bits(&mddev->flags, 0, VALID_MD_FLAGS);
??
But that can come later.
Thanks,
NeilBrown
Quoted 66 lines
drivers/md/raid0.c +2
-0@@ -580,6 +583,7 @@ static void *raid0_takeover_raid10(struct mddev *mddev) mddev->degraded =0 ;/* make sure it will be not marked as dirty */ mddev->recovery_cp = MaxSector; +clear_bit (MD_FAILFAST_SUPPORTED , &mddev->flags);create_strip_zones (mddev, &priv_conf);return priv_conf;@@ -622,6 +626,7 @@ static void *raid0_takeover_raid1(struct mddev *mddev) mddev->raid_disks =1 ;/* make sure it will be not marked as dirty */ mddev->recovery_cp = MaxSector; +clear_bit (MD_FAILFAST_SUPPORTED , &mddev->flags);create_strip_zones (mddev, &priv_conf);return priv_conf;drivers/md/raid1.c +4
-1@@ -3243,9 +3243,12 @@ static void *raid1_takeover(struct mddev *mddev) mddev->new_layout =0 ; mddev->new_chunk_sectors =0 ; conf =setup_conf (mddev); -if (!IS_ERR (conf)) +if (!IS_ERR (conf)) {/* Array must appear to be quiesced */ conf->array_frozen =1 ; +clear_bit (MD_HAS_JOURNAL , &mddev->flags); +clear_bit (MD_JOURNAL_CLEAN , &mddev->flags); + }return conf; }return ERR_PTR (-EINVAL );drivers/md/raid5.c +5
-1@@ -7811,6 +7811,7 @@ static void *raid45_takeover_raid0(struct mddev *mddev, int level)static void *raid5_takeover_raid1 (struct mddev *mddev) {int chunksect; +void *ret;if (mddev->raid_disks !=2 || mddev->degraded >1 )@@ -7832,7 +7833,10 @@ static void *raid5_takeover_raid1(struct mddev *mddev) mddev->new_layout =ALGORITHM_LEFT_SYMMETRIC ; mddev->new_chunk_sectors = chunksect; -return setup_conf (mddev); + ret =setup_conf (mddev); +if (!IS_ERR_VALUE (ret)) +clear_bit (MD_FAILFAST_SUPPORTED , &mddev->flags); +return ret; }static void *raid5_takeover_raid6 (struct mddev *mddev)Signature · 6 lines
2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-raid" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] md: takeover should clear unrelated bits
Quoted 26 lines · Neil Brown
Quoted 24 lines · Shaohua Li
When we change level from raid1 to raid5, the
MD_FAILFAST_SUPPORTEDbit will be accidentally set, but raid5 doesn't support it. The same is true for theMD_HAS_JOURNALbit.Fix: 46533ff (md: Use REQ_FAILFAST_* on metadata writes where appropriate)
Cc NeilBrown <[email protected]>Signed-off-by Shaohua Li <[email protected]>--- drivers/md/raid0.c | 5 +++++ drivers/md/raid1.c | 5 ++++- drivers/md/raid5.c | 6 +++++- 3 files changed, 14 insertions(+), 2 deletions(-)drivers/md/raid0.c +2
-0@@ -539,8 +539,11 @@ static void *raid0_takeover_raid45(struct mddev *mddev) mddev->delta_disks =-1 ;/* make sure it will be not marked as dirty */ mddev->recovery_cp = MaxSector; +clear_bit (MD_HAS_JOURNAL , &mddev->flags); +clear_bit (MD_JOURNAL_CLEAN , &mddev->flags);
Quoted 12 lines
drivers/md/raid0.c static void *raid0_takeover_raid45(struct mddev *mddev) · line 548
Quoted 4 lines
drivers/md/raid0.c +1
-0create_strip_zones (mddev, &priv_conf); +return priv_conf; }This looks like a good fix, but it is a little fragile. If a new bit is added, we would need to go through all the takeover functions and check if it needs to be cleared, and we would forget. It might be better if each personality defined a
VALID_MD_FLAGSor whatever, and the takeover function always did
set_mask_bits(&mddev->flags, 0, VALID_MD_FLAGS);
This is fragile indeed. My original idea is to clear the flags in level_store, but it doesn't work well as different personablities have different valid falgs. The suggestion looks good. Thanks for the review.
Thanks,
Shaohua
Quoted 75 lines
But that can come later.
Reviewed-by NeilBrown <[email protected]>Thanks,
NeilBrownQuoted 66 lines
drivers/md/raid0.c +2
-0@@ -580,6 +583,7 @@ static void *raid0_takeover_raid10(struct mddev *mddev) mddev->degraded =0 ;/* make sure it will be not marked as dirty */ mddev->recovery_cp = MaxSector; +clear_bit (MD_FAILFAST_SUPPORTED , &mddev->flags);create_strip_zones (mddev, &priv_conf);return priv_conf;@@ -622,6 +626,7 @@ static void *raid0_takeover_raid1(struct mddev *mddev) mddev->raid_disks =1 ;/* make sure it will be not marked as dirty */ mddev->recovery_cp = MaxSector; +clear_bit (MD_FAILFAST_SUPPORTED , &mddev->flags);create_strip_zones (mddev, &priv_conf);return priv_conf;drivers/md/raid1.c +4
-1@@ -3243,9 +3243,12 @@ static void *raid1_takeover(struct mddev *mddev) mddev->new_layout =0 ; mddev->new_chunk_sectors =0 ; conf =setup_conf (mddev); -if (!IS_ERR (conf)) +if (!IS_ERR (conf)) {/* Array must appear to be quiesced */ conf->array_frozen =1 ; +clear_bit (MD_HAS_JOURNAL , &mddev->flags); +clear_bit (MD_JOURNAL_CLEAN , &mddev->flags); + }return conf; }return ERR_PTR (-EINVAL );drivers/md/raid5.c +5
-1@@ -7811,6 +7811,7 @@ static void *raid45_takeover_raid0(struct mddev *mddev, int level)static void *raid5_takeover_raid1 (struct mddev *mddev) {int chunksect; +void *ret;if (mddev->raid_disks !=2 || mddev->degraded >1 )@@ -7832,7 +7833,10 @@ static void *raid5_takeover_raid1(struct mddev *mddev) mddev->new_layout =ALGORITHM_LEFT_SYMMETRIC ; mddev->new_chunk_sectors = chunksect; -return setup_conf (mddev); + ret =setup_conf (mddev); +if (!IS_ERR_VALUE (ret)) +clear_bit (MD_FAILFAST_SUPPORTED , &mddev->flags); +return ret; }static void *raid5_takeover_raid6 (struct mddev *mddev)Signature · 6 lines
2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-raid" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/3 md: MD_RECOVERY_NEEDED is set for mddev->recovery
In reply to Shaohua Li--- drivers/md/md.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/md.c +1 -1
@@ -6856,7 +6856,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,/* need to ensure recovery thread has run */ wait_event_interruptible_timeout (mddev->sb_wait, !test_bit (MD_RECOVERY_NEEDED , - &mddev->flags), + &mddev->recovery),msecs_to_jiffies (5000 ));if (cmd ==STOP_ARRAY || cmd ==STOP_ARRAY_RO ) {/* Need to flush page cache, and ensure no-one else opens
Signature · 1 line
2.9.3
Re: [PATCH 2/3] md: MD_RECOVERY_NEEDED is set for mddev->recovery
Quoted 20 lines · Shaohua Li
Signed-off-by Shaohua Li <[email protected]>--- drivers/md/md.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/md/md.c +1
-1@@ -6856,7 +6856,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,/* need to ensure recovery thread has run */ wait_event_interruptible_timeout (mddev->sb_wait, !test_bit (MD_RECOVERY_NEEDED , - &mddev->flags), + &mddev->recovery),msecs_to_jiffies (5000 ));if (cmd ==STOP_ARRAY || cmd ==STOP_ARRAY_RO ) {/* Need to flush page cache, and ensure no-one else opens Signature · 1 line
2.9.3
That was careless!
It would be good to add
to this.
Thanks,
NeilBrown
PATCH 3/3 md: separate flags for superblock changes
In reply to Shaohua LiThe mddev->flags are used for different purposes. There are a lot of places we check/change the flags without masking unrelated flags, we could check/change unrelated flags. These usage are most for superblock write, so spearate superblock related flags. This should make the code clearer and also fix real bugs.
--- drivers/md/bitmap.c | 4 +- drivers/md/dm-raid.c | 4 +- drivers/md/md.c | 115 ++++++++++++++++++++++++----------------------- drivers/md/md.h | 16 ++++--- drivers/md/multipath.c | 2 +- drivers/md/raid1.c | 12 ++--- drivers/md/raid10.c | 22 ++++----- drivers/md/raid5-cache.c | 6 +-- drivers/md/raid5.c | 26 +++++------ 9 files changed, 106 insertions(+), 101 deletions(-)
drivers/md/bitmap.c +2 -2
@@ -1623,7 +1623,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force) atomic_read(&bitmap->mddev->recovery_active) == 0); bitmap->mddev->curr_resync_completed = sector; -set_bit (MD_CHANGE_CLEAN , &bitmap->mddev->flags); +set_bit (MD_SB_CHANGE_CLEAN , &bitmap->mddev->sb_flags); sector &= ~((1ULL << bitmap->counts.chunkshift) -1 ); s =0 ;while (s < sector && s < bitmap->mddev->resync_max_sectors) {
@@ -2296,7 +2296,7 @@ location_store(struct mddev *mddev, const char *buf, size_t len)/* Ensure new bitmap info is stored in * metadata promptly. */ -set_bit (MD_CHANGE_DEVS , &mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags);md_wakeup_thread (mddev->thread); } rv =0 ;
drivers/md/dm-raid.c +2 -2
@@ -2011,7 +2011,7 @@ static int super_load(struct md_rdev *rdev, struct md_rdev *refdev) sb->compat_features =cpu_to_le32 (FEATURE_FLAG_SUPPORTS_V190 );/* Force writing of superblocks to disk */ -set_bit (MD_CHANGE_DEVS , &rdev->mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &rdev->mddev->sb_flags);/* Any superblock is better than none, choose that if given */ return refdev ?0 :1 ;
@@ -3497,7 +3497,7 @@ static void rs_update_sbs(struct raid_set *rs)struct mddev *mddev = &rs->md;int ro = mddev->ro; -set_bit (MD_CHANGE_DEVS , &mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags); mddev->ro =0 ;md_update_sb (mddev,1 ); mddev->ro = ro;
drivers/md/md.c +59 -56
374 lines not on this page · raw message
drivers/md/md.h +9 -7
@@ -213,9 +213,6 @@ extern int rdev_clear_badblocks(struct md_rdev *rdev, sector_t s, int sectors,struct md_cluster_info ;enum mddev_flags { -MD_CHANGE_DEVS ,/* Some device status has changed */ -MD_CHANGE_CLEAN ,/* transition to or from 'clean' */ -MD_CHANGE_PENDING ,/* switch from 'clean' to 'active' in progress */ MD_ARRAY_FIRST_USE ,/* First use of array, needs initialization */ MD_CLOSING ,/* If set, we are closing the array, do not open * it then */
@@ -231,11 +228,15 @@ enum mddev_flags {* supported as calls to md_error() will * never cause the array to become failed. */ - MD_NEED_REWRITE, /* metadata write needs to be repeated */ }; -#define MD_UPDATE_SB_FLAGS (BIT(MD_CHANGE_DEVS) | \ - BIT(MD_CHANGE_CLEAN) | \ - BIT(MD_CHANGE_PENDING))/* If these are set, md_update_sb needed */ + +enum mddev_sb_flags { +MD_SB_CHANGE_DEVS ,/* Some device status has changed */ +MD_SB_CHANGE_CLEAN ,/* transition to or from 'clean' */ +MD_SB_CHANGE_PENDING ,/* switch from 'clean' to 'active' in progress */ +MD_SB_NEED_REWRITE ,/* metadata write needs to be repeated */ +}; +struct mddev {void *private;struct md_personality *pers;
@@ -243,6 +244,7 @@ struct mddev {int md_minor;struct list_head disks;unsigned long flags; +unsigned long sb_flags;int suspended;atomic_t active_io;
drivers/md/multipath.c +1 -1
@@ -208,7 +208,7 @@ static void multipath_error (struct mddev *mddev, struct md_rdev *rdev)spin_unlock_irqrestore (&conf->device_lock, flags); }set_bit (Faulty, &rdev->flags); -set_bit (MD_CHANGE_DEVS , &mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags); pr_err("multipath: IO failure on %s, disabling IO path.\n" "multipath: Operation continuing on %d IO paths.\n", bdevname(rdev->bdev, b),
drivers/md/raid1.c +6 -6
@@ -1517,8 +1517,8 @@ static void raid1_error(struct mddev *mddev, struct md_rdev *rdev)* if recovery is running, make sure it aborts. */ set_bit (MD_RECOVERY_INTR , &mddev->recovery); -set_mask_bits (&mddev->flags,0 , -BIT (MD_CHANGE_DEVS ) |BIT (MD_CHANGE_PENDING )); +set_mask_bits (&mddev->sb_flags,0 , +BIT (MD_SB_CHANGE_DEVS ) |BIT (MD_SB_CHANGE_PENDING )); pr_crit("md/raid1:%s: Disk failure on %s, disabling device.\n" "md/raid1:%s: Operation continuing on %d devices.\n", mdname(mddev), bdevname(rdev->bdev, b),
@@ -2464,10 +2464,10 @@ static void raid1d(struct md_thread *thread)md_check_recovery (mddev);if (!list_empty_careful (&conf->bio_end_io_list) && - !test_bit (MD_CHANGE_PENDING , &mddev->flags)) { + !test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags)) {LIST_HEAD (tmp);spin_lock_irqsave (&conf->device_lock, flags); -if (!test_bit (MD_CHANGE_PENDING , &mddev->flags)) { +if (!test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags)) {while (!list_empty (&conf->bio_end_io_list)) {list_move (conf->bio_end_io_list.prev, &tmp); conf->nr_queued--;
@@ -2521,7 +2521,7 @@ static void raid1d(struct md_thread *thread)generic_make_request (r1_bio->bios[r1_bio->read_disk]);cond_resched (); -if (mddev->flags & ~(1 <<MD_CHANGE_PENDING )) +if (mddev->sb_flags & ~(1 <<MD_SB_CHANGE_PENDING ))md_check_recovery (mddev); }blk_finish_plug (&plug);
@@ -2724,7 +2724,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr, min_bad,0 ) && ok; } -set_bit (MD_CHANGE_DEVS , &mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags); *skipped =1 ;put_buf (r1_bio);
drivers/md/raid10.c +11 -11
@@ -1138,12 +1138,12 @@ static void __make_request(struct mddev *mddev, struct bio *bio) bio->bi_iter.bi_sector < conf->reshape_progress))) {/* Need to update reshape_position in metadata */ mddev->reshape_position = conf->reshape_progress; -set_mask_bits (&mddev->flags,0 , -BIT (MD_CHANGE_DEVS ) |BIT (MD_CHANGE_PENDING )); +set_mask_bits (&mddev->sb_flags,0 , +BIT (MD_SB_CHANGE_DEVS ) |BIT (MD_SB_CHANGE_PENDING ));md_wakeup_thread (mddev->thread);raid10_log (conf->mddev,"wait reshape metadata" );wait_event (mddev->sb_wait, - !test_bit (MD_CHANGE_PENDING , &mddev->flags)); + !test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags)); conf->reshape_safe = mddev->reshape_position; }
@@ -1652,8 +1652,8 @@ static void raid10_error(struct mddev *mddev, struct md_rdev *rdev)set_bit (MD_RECOVERY_INTR , &mddev->recovery);set_bit (Blocked, &rdev->flags);set_bit (Faulty, &rdev->flags); -set_mask_bits (&mddev->flags,0 , -BIT (MD_CHANGE_DEVS ) |BIT (MD_CHANGE_PENDING )); +set_mask_bits (&mddev->sb_flags,0 , +BIT (MD_SB_CHANGE_DEVS ) |BIT (MD_SB_CHANGE_PENDING ));spin_unlock_irqrestore (&conf->device_lock, flags); pr_crit("md/raid10:%s: Disk failure on %s, disabling device.\n" "md/raid10:%s: Operation continuing on %d devices.\n",
@@ -2761,10 +2761,10 @@ static void raid10d(struct md_thread *thread)md_check_recovery (mddev);if (!list_empty_careful (&conf->bio_end_io_list) && - !test_bit (MD_CHANGE_PENDING , &mddev->flags)) { + !test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags)) {LIST_HEAD (tmp);spin_lock_irqsave (&conf->device_lock, flags); -if (!test_bit (MD_CHANGE_PENDING , &mddev->flags)) { +if (!test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags)) {while (!list_empty (&conf->bio_end_io_list)) {list_move (conf->bio_end_io_list.prev, &tmp); conf->nr_queued--;
@@ -2822,7 +2822,7 @@ static void raid10d(struct md_thread *thread) }cond_resched (); -if (mddev->flags & ~(1 <<MD_CHANGE_PENDING )) +if (mddev->sb_flags & ~(1 <<MD_SB_CHANGE_PENDING ))md_check_recovery (mddev); }blk_finish_plug (&plug);
@@ -4209,7 +4209,7 @@ static int raid10_start_reshape(struct mddev *mddev)spin_unlock_irq (&conf->device_lock); mddev->raid_disks = conf->geo.raid_disks; mddev->reshape_position = conf->reshape_progress; -set_bit (MD_CHANGE_DEVS , &mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags);clear_bit (MD_RECOVERY_SYNC , &mddev->recovery);clear_bit (MD_RECOVERY_CHECK , &mddev->recovery);
@@ -4404,9 +4404,9 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,else mddev->curr_resync_completed = conf->reshape_progress; conf->reshape_checkpoint = jiffies; -set_bit (MD_CHANGE_DEVS , &mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags);md_wakeup_thread (mddev->thread); -wait_event (mddev->sb_wait, mddev->flags ==0 || +wait_event (mddev->sb_wait, mddev->sb_flags ==0 ||test_bit (MD_RECOVERY_INTR , &mddev->recovery));if (test_bit (MD_RECOVERY_INTR , &mddev->recovery)) {allow_barrier (conf);
drivers/md/raid5-cache.c +3 -3
@@ -1206,8 +1206,8 @@ static void r5l_write_super_and_discard_space(struct r5l_log *log,* there is a deadlock. We workaround this issue with a trylock. * FIXME: we could miss discard if we can't take reconfig mutex */ -set_mask_bits (&mddev->flags,0 , -BIT (MD_CHANGE_DEVS ) |BIT (MD_CHANGE_PENDING )); +set_mask_bits (&mddev->sb_flags,0 , +BIT (MD_SB_CHANGE_DEVS ) |BIT (MD_SB_CHANGE_PENDING ));if (!mddev_trylock (mddev))return ;md_update_sb (mddev,1 );
@@ -2197,7 +2197,7 @@ static void r5l_write_super(struct r5l_log *log, sector_t cp)struct mddev *mddev = log->rdev->mddev; log->rdev->journal_tail = cp; -set_bit (MD_CHANGE_DEVS , &mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags); }static ssize_t r5c_journal_mode_show (struct mddev *mddev,char *page)
drivers/md/raid5.c +13 -13
@@ -961,7 +961,7 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)if (bad <0 ) {set_bit (BlockedBadBlocks, &rdev->flags);if (!conf->mddev->external && - conf->mddev->flags) { + conf->mddev->sb_flags) {/* It is very unlikely, but we might * still need to write out the * bad block log - better give it
@@ -2547,8 +2547,8 @@ static void raid5_error(struct mddev *mddev, struct md_rdev *rdev)set_bit (Blocked, &rdev->flags);set_bit (Faulty, &rdev->flags); -set_mask_bits (&mddev->flags,0 , -BIT (MD_CHANGE_DEVS ) |BIT (MD_CHANGE_PENDING )); +set_mask_bits (&mddev->sb_flags,0 , +BIT (MD_SB_CHANGE_DEVS ) |BIT (MD_SB_CHANGE_PENDING )); pr_crit("md/raid:%s: Disk failure on %s, disabling device.\n" "md/raid:%s: Operation continuing on %d devices.\n", mdname(mddev),
@@ -4761,7 +4761,7 @@ static void handle_stripe(struct stripe_head *sh) }if (!bio_list_empty (&s.return_bi)) { -if (test_bit (MD_CHANGE_PENDING , &conf->mddev->flags)) { +if (test_bit (MD_SB_CHANGE_PENDING , &conf->mddev->sb_flags)) {spin_lock_irq (&conf->device_lock);bio_list_merge (&conf->return_bi, &s.return_bi);spin_unlock_irq (&conf->device_lock);
@@ -5617,9 +5617,9 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk mddev->reshape_position = conf->reshape_progress; mddev->curr_resync_completed = sector_nr; conf->reshape_checkpoint = jiffies; -set_bit (MD_CHANGE_DEVS , &mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags);md_wakeup_thread (mddev->thread); -wait_event (mddev->sb_wait, mddev->flags ==0 || +wait_event (mddev->sb_wait, mddev->sb_flags ==0 ||test_bit (MD_RECOVERY_INTR , &mddev->recovery));if (test_bit (MD_RECOVERY_INTR , &mddev->recovery))return 0 ;
@@ -5715,10 +5715,10 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk mddev->reshape_position = conf->reshape_progress; mddev->curr_resync_completed = sector_nr; conf->reshape_checkpoint = jiffies; -set_bit (MD_CHANGE_DEVS , &mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags);md_wakeup_thread (mddev->thread);wait_event (mddev->sb_wait, - !test_bit (MD_CHANGE_DEVS , &mddev->flags) + !test_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags) ||test_bit (MD_RECOVERY_INTR , &mddev->recovery));if (test_bit (MD_RECOVERY_INTR , &mddev->recovery)) goto ret;
@@ -5993,10 +5993,10 @@ static void raid5d(struct md_thread *thread)md_check_recovery (mddev);if (!bio_list_empty (&conf->return_bi) && - !test_bit (MD_CHANGE_PENDING , &mddev->flags)) { + !test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags)) {struct bio_list tmp =BIO_EMPTY_LIST ;spin_lock_irq (&conf->device_lock); -if (!test_bit (MD_CHANGE_PENDING , &mddev->flags)) { +if (!test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags)) {bio_list_merge (&tmp, &conf->return_bi);bio_list_init (&conf->return_bi); }
@@ -6043,7 +6043,7 @@ static void raid5d(struct md_thread *thread)break ; handled += batch_size; -if (mddev->flags & ~(1 <<MD_CHANGE_PENDING )) { +if (mddev->sb_flags & ~(1 <<MD_SB_CHANGE_PENDING )) {spin_unlock_irq (&conf->device_lock);md_check_recovery (mddev);spin_lock_irq (&conf->device_lock);
@@ -7640,7 +7640,7 @@ static int raid5_start_reshape(struct mddev *mddev) } mddev->raid_disks = conf->raid_disks; mddev->reshape_position = conf->reshape_progress; -set_bit (MD_CHANGE_DEVS , &mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags);clear_bit (MD_RECOVERY_SYNC , &mddev->recovery);clear_bit (MD_RECOVERY_CHECK , &mddev->recovery);
@@ -7906,7 +7906,7 @@ static int raid5_check_reshape(struct mddev *mddev) conf->chunk_sectors = new_chunk ; mddev->chunk_sectors = new_chunk; } -set_bit (MD_CHANGE_DEVS , &mddev->flags); +set_bit (MD_SB_CHANGE_DEVS , &mddev->sb_flags);md_wakeup_thread (mddev->thread); }return check_reshape (mddev);
Signature · 1 line
2.9.3
Re: [PATCH 3/3] md: separate flags for superblock changes
Quoted 7 lines · Shaohua Li
The
mddev->flagsare used for different purposes. There are a lot of places we check/change the flags without masking unrelated flags, we could check/change unrelated flags. These usage are most for superblock write, so spearate superblock related flags. This should make the code clearer and also fix real bugs.Signed-off-by Shaohua Li <[email protected]>
That real bug would be:
drivers/md/raid10.c static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, · line 4410
Quoted 4 lines
drivers/md/raid10.c +1
-1md_wakeup_thread (mddev->thread); -wait_event (mddev->sb_wait, mddev->flags ==0 || +wait_event (mddev->sb_wait, mddev->sb_flags ==0 ||test_bit (MD_RECOVERY_INTR , &mddev->recovery));
??
mddev->flags used to be called mddev->sb_dirty, before
Commit: 850b2b420cd5 ("[PATCH] md: replace magic numbers in sb_dirty with well defined bit flags")
Then we added lots of other flags. Now we are going back to the same idea :-)
Thanks,
NeilBrown
Re: [PATCH 3/3] md: separate flags for superblock changes
Quoted 8 lines · Neil Brown
Quoted 6 lines · Shaohua Li
The
mddev->flagsare used for different purposes. There are a lot of places we check/change the flags without masking unrelated flags, we could check/change unrelated flags. These usage are most for superblock write, so spearate superblock related flags. This should make the code clearer and also fix real bugs.
Quoted 8 lines
Quoted 1 line
Signed-off-by Shaohua Li <[email protected]>That real bug would be:
drivers/md/raid10.c static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, · line 4410
Quoted 4 lines
drivers/md/raid10.c +1
-1md_wakeup_thread (mddev->thread); -wait_event (mddev->sb_wait, mddev->flags ==0 || +wait_event (mddev->sb_wait, mddev->sb_flags ==0 ||test_bit (MD_RECOVERY_INTR , &mddev->recovery));
Yes, for the reshape hang.
Quoted 11 lines
mddev->flagsused to be calledmddev->sb_dirty, before
Commit:850b2b420cd5("[PATCH] md: replace magic numbers insb_dirtywith well defined bit flags")Then we added lots of other flags. Now we are going back to the same idea :-)
Reviewed-by NeilBrown <[email protected]>Thanks,
NeilBrown