diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 185 |
1 files changed, 84 insertions, 101 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 707e802d0082..8273ac5eef06 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1021,8 +1021,6 @@ EXPORT_SYMBOL_GPL(sync_page_io); static int read_disk_sb(struct md_rdev *rdev, int size) { - char b[BDEVNAME_SIZE]; - if (rdev->sb_loaded) return 0; @@ -1032,8 +1030,8 @@ static int read_disk_sb(struct md_rdev *rdev, int size) return 0; fail: - pr_err("md: disabled device %s, could not read superblock.\n", - bdevname(rdev->bdev,b)); + pr_err("md: disabled device %pg, could not read superblock.\n", + rdev->bdev); return -EINVAL; } @@ -1179,7 +1177,6 @@ EXPORT_SYMBOL(md_check_no_bitmap); */ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_version) { - char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; mdp_super_t *sb; int ret; bool spare_disk = true; @@ -1198,19 +1195,19 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor ret = -EINVAL; - bdevname(rdev->bdev, b); sb = page_address(rdev->sb_page); if (sb->md_magic != MD_SB_MAGIC) { - pr_warn("md: invalid raid superblock magic on %s\n", b); + pr_warn("md: invalid raid superblock magic on %pg\n", + rdev->bdev); goto abort; } if (sb->major_version != 0 || sb->minor_version < 90 || sb->minor_version > 91) { - pr_warn("Bad version number %d.%d on %s\n", - sb->major_version, sb->minor_version, b); + pr_warn("Bad version number %d.%d on %pg\n", + sb->major_version, sb->minor_version, rdev->bdev); goto abort; } @@ -1218,7 +1215,7 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor goto abort; if (md_csum_fold(calc_sb_csum(sb)) != md_csum_fold(sb->sb_csum)) { - pr_warn("md: invalid superblock checksum on %s\n", b); + pr_warn("md: invalid superblock checksum on %pg\n", rdev->bdev); goto abort; } @@ -1250,13 +1247,13 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor __u64 ev1, ev2; mdp_super_t *refsb = page_address(refdev->sb_page); if (!md_uuid_equal(refsb, sb)) { - pr_warn("md: %s has different UUID to %s\n", - b, bdevname(refdev->bdev,b2)); + pr_warn("md: %pg has different UUID to %pg\n", + rdev->bdev, refdev->bdev); goto abort; } if (!md_sb_equal(refsb, sb)) { - pr_warn("md: %s has same UUID but different superblock to %s\n", - b, bdevname(refdev->bdev, b2)); + pr_warn("md: %pg has same UUID but different superblock to %pg\n", + rdev->bdev, refdev->bdev); goto abort; } ev1 = md_event(sb); @@ -1620,7 +1617,6 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ int ret; sector_t sb_start; sector_t sectors; - char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; int bmask; bool spare_disk = true; @@ -1664,13 +1660,13 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ return -EINVAL; if (calc_sb_1_csum(sb) != sb->sb_csum) { - pr_warn("md: invalid superblock checksum on %s\n", - bdevname(rdev->bdev,b)); + pr_warn("md: invalid superblock checksum on %pg\n", + rdev->bdev); return -EINVAL; } if (le64_to_cpu(sb->data_size) < 10) { - pr_warn("md: data_size too small on %s\n", - bdevname(rdev->bdev,b)); + pr_warn("md: data_size too small on %pg\n", + rdev->bdev); return -EINVAL; } if (sb->pad0 || @@ -1776,9 +1772,9 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ sb->level != refsb->level || sb->layout != refsb->layout || sb->chunksize != refsb->chunksize) { - pr_warn("md: %s has strangely different superblock to %s\n", - bdevname(rdev->bdev,b), - bdevname(refdev->bdev,b2)); + pr_warn("md: %pg has strangely different superblock to %pg\n", + rdev->bdev, + refdev->bdev); return -EINVAL; } ev1 = le64_to_cpu(sb->events); @@ -2365,7 +2361,6 @@ EXPORT_SYMBOL(md_integrity_register); int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev) { struct blk_integrity *bi_mddev; - char name[BDEVNAME_SIZE]; if (!mddev->gendisk) return 0; @@ -2376,8 +2371,8 @@ int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev) return 0; if (blk_integrity_compare(mddev->gendisk, rdev->bdev->bd_disk) != 0) { - pr_err("%s: incompatible integrity profile for %s\n", - mdname(mddev), bdevname(rdev->bdev, name)); + pr_err("%s: incompatible integrity profile for %pg\n", + mdname(mddev), rdev->bdev); return -ENXIO; } @@ -2486,11 +2481,9 @@ static void rdev_delayed_delete(struct work_struct *ws) static void unbind_rdev_from_array(struct md_rdev *rdev) { - char b[BDEVNAME_SIZE]; - bd_unlink_disk_holder(rdev->bdev, rdev->mddev->gendisk); list_del_rcu(&rdev->same_set); - pr_debug("md: unbind<%s>\n", bdevname(rdev->bdev,b)); + pr_debug("md: unbind<%pg>\n", rdev->bdev); mddev_destroy_serial_pool(rdev->mddev, rdev, false); rdev->mddev = NULL; sysfs_remove_link(&rdev->kobj, "block"); @@ -2543,9 +2536,7 @@ void md_autodetect_dev(dev_t dev); static void export_rdev(struct md_rdev *rdev) { - char b[BDEVNAME_SIZE]; - - pr_debug("md: export_rdev(%s)\n", bdevname(rdev->bdev,b)); + pr_debug("md: export_rdev(%pg)\n", rdev->bdev); md_rdev_clear(rdev); #ifndef MODULE if (test_bit(AutoDetected, &rdev->flags)) @@ -2803,8 +2794,6 @@ repeat: rewrite: md_bitmap_update_sb(mddev->bitmap); rdev_for_each(rdev, mddev) { - char b[BDEVNAME_SIZE]; - if (rdev->sb_loaded != 1) continue; /* no noise on spare devices */ @@ -2812,8 +2801,8 @@ rewrite: md_super_write(mddev,rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); - pr_debug("md: (write) %s's sb offset: %llu\n", - bdevname(rdev->bdev, b), + pr_debug("md: (write) %pg's sb offset: %llu\n", + rdev->bdev, (unsigned long long)rdev->sb_start); rdev->sb_events = mddev->events; if (rdev->badblocks.size) { @@ -2825,8 +2814,8 @@ rewrite: } } else - pr_debug("md: %s (skipping faulty)\n", - bdevname(rdev->bdev, b)); + pr_debug("md: %pg (skipping faulty)\n", + rdev->bdev); if (mddev->level == LEVEL_MULTIPATH) /* only need to write one superblock... */ @@ -3701,7 +3690,6 @@ EXPORT_SYMBOL_GPL(md_rdev_init); */ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int super_minor) { - char b[BDEVNAME_SIZE]; int err; struct md_rdev *rdev; sector_t size; @@ -3725,8 +3713,8 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe size = bdev_nr_bytes(rdev->bdev) >> BLOCK_SIZE_BITS; if (!size) { - pr_warn("md: %s has zero or unknown size, marking faulty!\n", - bdevname(rdev->bdev,b)); + pr_warn("md: %pg has zero or unknown size, marking faulty!\n", + rdev->bdev); err = -EINVAL; goto abort_free; } @@ -3735,14 +3723,14 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe err = super_types[super_format]. load_super(rdev, NULL, super_minor); if (err == -EINVAL) { - pr_warn("md: %s does not have a valid v%d.%d superblock, not importing!\n", - bdevname(rdev->bdev,b), + pr_warn("md: %pg does not have a valid v%d.%d superblock, not importing!\n", + rdev->bdev, super_format, super_minor); goto abort_free; } if (err < 0) { - pr_warn("md: could not read %s's sb, not importing!\n", - bdevname(rdev->bdev,b)); + pr_warn("md: could not read %pg's sb, not importing!\n", + rdev->bdev); goto abort_free; } } @@ -3765,7 +3753,6 @@ static int analyze_sbs(struct mddev *mddev) { int i; struct md_rdev *rdev, *freshest, *tmp; - char b[BDEVNAME_SIZE]; freshest = NULL; rdev_for_each_safe(rdev, tmp, mddev) @@ -3777,8 +3764,8 @@ static int analyze_sbs(struct mddev *mddev) case 0: break; default: - pr_warn("md: fatal superblock inconsistency in %s -- removing from array\n", - bdevname(rdev->bdev,b)); + pr_warn("md: fatal superblock inconsistency in %pg -- removing from array\n", + rdev->bdev); md_kick_rdev_from_array(rdev); } @@ -3796,8 +3783,8 @@ static int analyze_sbs(struct mddev *mddev) if (mddev->max_disks && (rdev->desc_nr >= mddev->max_disks || i > mddev->max_disks)) { - pr_warn("md: %s: %s: only %d devices permitted\n", - mdname(mddev), bdevname(rdev->bdev, b), + pr_warn("md: %s: %pg: only %d devices permitted\n", + mdname(mddev), rdev->bdev, mddev->max_disks); md_kick_rdev_from_array(rdev); continue; @@ -3805,8 +3792,8 @@ static int analyze_sbs(struct mddev *mddev) if (rdev != freshest) { if (super_types[mddev->major_version]. validate_super(mddev, rdev)) { - pr_warn("md: kicking non-fresh %s from array!\n", - bdevname(rdev->bdev,b)); + pr_warn("md: kicking non-fresh %pg from array!\n", + rdev->bdev); md_kick_rdev_from_array(rdev); continue; } @@ -4844,7 +4831,7 @@ action_store(struct mddev *mddev, const char *page, size_t len) flush_workqueue(md_misc_wq); if (mddev->sync_thread) { set_bit(MD_RECOVERY_INTR, &mddev->recovery); - md_reap_sync_thread(mddev); + md_reap_sync_thread(mddev, true); } mddev_unlock(mddev); } @@ -5598,8 +5585,6 @@ static void md_free(struct kobject *ko) bioset_exit(&mddev->bio_set); bioset_exit(&mddev->sync_set); - if (mddev->level != 1 && mddev->level != 10) - bioset_exit(&mddev->io_acct_set); kfree(mddev); } @@ -5912,7 +5897,6 @@ int md_run(struct mddev *mddev) /* Warn if this is a potentially silly * configuration. */ - char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; struct md_rdev *rdev2; int warned = 0; @@ -5921,10 +5905,10 @@ int md_run(struct mddev *mddev) if (rdev < rdev2 && rdev->bdev->bd_disk == rdev2->bdev->bd_disk) { - pr_warn("%s: WARNING: %s appears to be on the same physical disk as %s.\n", + pr_warn("%s: WARNING: %pg appears to be on the same physical disk as %pg.\n", mdname(mddev), - bdevname(rdev->bdev,b), - bdevname(rdev2->bdev,b2)); + rdev->bdev, + rdev2->bdev); warned = 1; } } @@ -6213,7 +6197,7 @@ static void __md_stop_writes(struct mddev *mddev) flush_workqueue(md_misc_wq); if (mddev->sync_thread) { set_bit(MD_RECOVERY_INTR, &mddev->recovery); - md_reap_sync_thread(mddev); + md_reap_sync_thread(mddev, true); } del_timer_sync(&mddev->safemode_timer); @@ -6285,8 +6269,6 @@ void md_stop(struct mddev *mddev) __md_stop(mddev); bioset_exit(&mddev->bio_set); bioset_exit(&mddev->sync_set); - if (mddev->level != 1 && mddev->level != 10) - bioset_exit(&mddev->io_acct_set); } EXPORT_SYMBOL_GPL(md_stop); @@ -6452,8 +6434,7 @@ static void autorun_array(struct mddev *mddev) pr_info("md: running: "); rdev_for_each(rdev, mddev) { - char b[BDEVNAME_SIZE]; - pr_cont("<%s>", bdevname(rdev->bdev,b)); + pr_cont("<%pg>", rdev->bdev); } pr_cont("\n"); @@ -6480,7 +6461,6 @@ static void autorun_devices(int part) { struct md_rdev *rdev0, *rdev, *tmp; struct mddev *mddev; - char b[BDEVNAME_SIZE]; pr_info("md: autorun ...\n"); while (!list_empty(&pending_raid_disks)) { @@ -6490,12 +6470,12 @@ static void autorun_devices(int part) rdev0 = list_entry(pending_raid_disks.next, struct md_rdev, same_set); - pr_debug("md: considering %s ...\n", bdevname(rdev0->bdev,b)); + pr_debug("md: considering %pg ...\n", rdev0->bdev); INIT_LIST_HEAD(&candidates); rdev_for_each_list(rdev, tmp, &pending_raid_disks) if (super_90_load(rdev, rdev0, 0) >= 0) { - pr_debug("md: adding %s ...\n", - bdevname(rdev->bdev,b)); + pr_debug("md: adding %pg ...\n", + rdev->bdev); list_move(&rdev->same_set, &candidates); } /* @@ -6512,8 +6492,8 @@ static void autorun_devices(int part) unit = MINOR(dev); } if (rdev0->preferred_minor != unit) { - pr_warn("md: unit number in %s is bad: %d\n", - bdevname(rdev0->bdev, b), rdev0->preferred_minor); + pr_warn("md: unit number in %pg is bad: %d\n", + rdev0->bdev, rdev0->preferred_minor); break; } @@ -6526,8 +6506,8 @@ static void autorun_devices(int part) pr_warn("md: %s locked, cannot run\n", mdname(mddev)); else if (mddev->raid_disks || mddev->major_version || !list_empty(&mddev->disks)) { - pr_warn("md: %s already running, cannot run %s\n", - mdname(mddev), bdevname(rdev0->bdev,b)); + pr_warn("md: %s already running, cannot run %pg\n", + mdname(mddev), rdev0->bdev); mddev_unlock(mddev); } else { pr_debug("md: created %s\n", mdname(mddev)); @@ -6701,7 +6681,6 @@ static int get_disk_info(struct mddev *mddev, void __user * arg) int md_add_new_disk(struct mddev *mddev, struct mdu_disk_info_s *info) { - char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; struct md_rdev *rdev; dev_t dev = MKDEV(info->major,info->minor); @@ -6731,9 +6710,9 @@ int md_add_new_disk(struct mddev *mddev, struct mdu_disk_info_s *info) err = super_types[mddev->major_version] .load_super(rdev, rdev0, mddev->minor_version); if (err < 0) { - pr_warn("md: %s has different UUID to %s\n", - bdevname(rdev->bdev,b), - bdevname(rdev0->bdev,b2)); + pr_warn("md: %pg has different UUID to %pg\n", + rdev->bdev, + rdev0->bdev); export_rdev(rdev); return -EINVAL; } @@ -6908,7 +6887,6 @@ int md_add_new_disk(struct mddev *mddev, struct mdu_disk_info_s *info) static int hot_remove_disk(struct mddev *mddev, dev_t dev) { - char b[BDEVNAME_SIZE]; struct md_rdev *rdev; if (!mddev->pers) @@ -6943,14 +6921,13 @@ kick_rdev: return 0; busy: - pr_debug("md: cannot remove active disk %s from %s ...\n", - bdevname(rdev->bdev,b), mdname(mddev)); + pr_debug("md: cannot remove active disk %pg from %s ...\n", + rdev->bdev, mdname(mddev)); return -EBUSY; } static int hot_add_disk(struct mddev *mddev, dev_t dev) { - char b[BDEVNAME_SIZE]; int err; struct md_rdev *rdev; @@ -6983,8 +6960,8 @@ static int hot_add_disk(struct mddev *mddev, dev_t dev) rdev->sectors = rdev->sb_start; if (test_bit(Faulty, &rdev->flags)) { - pr_warn("md: can not hot-add faulty %s disk to %s!\n", - bdevname(rdev->bdev,b), mdname(mddev)); + pr_warn("md: can not hot-add faulty %pg disk to %s!\n", + rdev->bdev, mdname(mddev)); err = -EINVAL; goto abort_export; } @@ -7011,8 +6988,8 @@ static int hot_add_disk(struct mddev *mddev, dev_t dev) * disable on the whole MD. */ if (!blk_queue_nowait(bdev_get_queue(rdev->bdev))) { - pr_info("%s: Disabling nowait because %s does not support nowait\n", - mdname(mddev), bdevname(rdev->bdev, b)); + pr_info("%s: Disabling nowait because %pg does not support nowait\n", + mdname(mddev), rdev->bdev); blk_queue_flag_clear(QUEUE_FLAG_NOWAIT, mddev->queue); } /* @@ -7963,17 +7940,22 @@ EXPORT_SYMBOL(md_register_thread); void md_unregister_thread(struct md_thread **threadp) { - struct md_thread *thread = *threadp; - if (!thread) - return; - pr_debug("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); - /* Locking ensures that mddev_unlock does not wake_up a + struct md_thread *thread; + + /* + * Locking ensures that mddev_unlock does not wake_up a * non-existent thread */ spin_lock(&pers_lock); + thread = *threadp; + if (!thread) { + spin_unlock(&pers_lock); + return; + } *threadp = NULL; spin_unlock(&pers_lock); + pr_debug("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); kthread_stop(thread->tsk); kfree(thread); } @@ -8012,10 +7994,8 @@ static void status_unused(struct seq_file *seq) seq_printf(seq, "unused devices: "); list_for_each_entry(rdev, &pending_raid_disks, same_set) { - char b[BDEVNAME_SIZE]; i++; - seq_printf(seq, "%s ", - bdevname(rdev->bdev,b)); + seq_printf(seq, "%pg ", rdev->bdev); } if (!i) seq_printf(seq, "<none>"); @@ -8255,9 +8235,8 @@ static int md_seq_show(struct seq_file *seq, void *v) sectors = 0; rcu_read_lock(); rdev_for_each_rcu(rdev, mddev) { - char b[BDEVNAME_SIZE]; - seq_printf(seq, " %s[%d]", - bdevname(rdev->bdev,b), rdev->desc_nr); + seq_printf(seq, " %pg[%d]", rdev->bdev, rdev->desc_nr); + if (test_bit(WriteMostly, &rdev->flags)) seq_printf(seq, "(W)"); if (test_bit(Journal, &rdev->flags)) @@ -9324,7 +9303,7 @@ void md_check_recovery(struct mddev *mddev) * ->spare_active and clear saved_raid_disk */ set_bit(MD_RECOVERY_INTR, &mddev->recovery); - md_reap_sync_thread(mddev); + md_reap_sync_thread(mddev, true); clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery); clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); clear_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags); @@ -9359,7 +9338,7 @@ void md_check_recovery(struct mddev *mddev) goto unlock; } if (mddev->sync_thread) { - md_reap_sync_thread(mddev); + md_reap_sync_thread(mddev, true); goto unlock; } /* Set RUNNING before clearing NEEDED to avoid @@ -9432,14 +9411,18 @@ void md_check_recovery(struct mddev *mddev) } EXPORT_SYMBOL(md_check_recovery); -void md_reap_sync_thread(struct mddev *mddev) +void md_reap_sync_thread(struct mddev *mddev, bool reconfig_mutex_held) { struct md_rdev *rdev; sector_t old_dev_sectors = mddev->dev_sectors; bool is_reshaped = false; + if (reconfig_mutex_held) + mddev_unlock(mddev); /* resync has finished, collect result */ md_unregister_thread(&mddev->sync_thread); + if (reconfig_mutex_held) + mddev_lock_nointr(mddev); if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && mddev->degraded != mddev->raid_disks) { @@ -9652,7 +9635,6 @@ static void check_sb_changes(struct mddev *mddev, struct md_rdev *rdev) struct mdp_superblock_1 *sb = page_address(rdev->sb_page); struct md_rdev *rdev2, *tmp; int role, ret; - char b[BDEVNAME_SIZE]; /* * If size is changed in another node then we need to @@ -9676,7 +9658,8 @@ static void check_sb_changes(struct mddev *mddev, struct md_rdev *rdev) if (test_bit(Candidate, &rdev2->flags)) { if (role == MD_DISK_ROLE_FAULTY) { - pr_info("md: Removing Candidate device %s because add failed\n", bdevname(rdev2->bdev,b)); + pr_info("md: Removing Candidate device %pg because add failed\n", + rdev2->bdev); md_kick_rdev_from_array(rdev2); continue; } @@ -9693,8 +9676,8 @@ static void check_sb_changes(struct mddev *mddev, struct md_rdev *rdev) MD_FEATURE_RESHAPE_ACTIVE)) { rdev2->saved_raid_disk = role; ret = remove_and_add_spares(mddev, rdev2); - pr_info("Activated spare: %s\n", - bdevname(rdev2->bdev,b)); + pr_info("Activated spare: %pg\n", + rdev2->bdev); /* wakeup mddev->thread here, so array could * perform resync with the new activated disk */ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |