diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-06-03 10:25:56 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-06-03 10:25:56 -0700 |
commit | 78c6499c92090d0fd1ddd1684fc3a5dc41d98c92 (patch) | |
tree | 2459aac592803b4be762457f91ed3a4e45877c6a | |
parent | 72fbbc3d0e3e3117c29a73d0b4d928dc00ed99ce (diff) | |
parent | aacae8c469f9ce4b303a2eb61593ff522c1420bc (diff) | |
download | lwn-78c6499c92090d0fd1ddd1684fc3a5dc41d98c92.tar.gz lwn-78c6499c92090d0fd1ddd1684fc3a5dc41d98c92.zip |
Merge tag 'for-5.19/drivers-2022-06-02' of git://git.kernel.dk/linux-block
Pull more block driver updates from Jens Axboe:
"A collection of stragglers that were late on sending in their changes
and just followup fixes.
- NVMe fixes pull request via Christoph:
- set controller enable bit in a separate write (Niklas Cassel)
- disable namespace identifiers for the MAXIO MAP1001 (Christoph)
- fix a comment typo (Julia Lawall)"
- MD fixes pull request via Song:
- Remove uses of bdevname (Christoph Hellwig)
- Bug fixes (Guoqing Jiang, and Xiao Ni)
- bcache fixes series (Coly)
- null_blk zoned write fix (Damien)
- nbd fixes (Yu, Zhang)
- Fix for loop partition scanning (Christoph)"
* tag 'for-5.19/drivers-2022-06-02' of git://git.kernel.dk/linux-block: (23 commits)
block: null_blk: Fix null_zone_write()
nvmet: fix typo in comment
nvme: set controller enable bit in a separate write
nvme-pci: disable namespace identifiers for the MAXIO MAP1001
bcache: avoid unnecessary soft lockup in kworker update_writeback_rate()
nbd: use pr_err to output error message
nbd: fix possible overflow on 'first_minor' in nbd_dev_add()
nbd: fix io hung while disconnecting device
nbd: don't clear 'NBD_CMD_INFLIGHT' flag if request is not completed
nbd: fix race between nbd_alloc_config() and module removal
nbd: call genl_unregister_family() first in nbd_cleanup()
md: bcache: check the return value of kzalloc() in detached_dev_do_request()
bcache: memset on stack variables in bch_btree_check() and bch_sectors_dirty_init()
block, loop: support partitions without scanning
bcache: avoid journal no-space deadlock by reserving 1 journal bucket
bcache: remove incremental dirty sector counting for bch_sectors_dirty_init()
bcache: improve multithreaded bch_sectors_dirty_init()
bcache: improve multithreaded bch_btree_check()
md: fix double free of io_acct_set bioset
md: Don't set mddev private to NULL in raid0 pers->free
...
30 files changed, 395 insertions, 391 deletions
diff --git a/block/genhd.c b/block/genhd.c index 36532b931841..27205ae47d59 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -385,6 +385,8 @@ int disk_scan_partitions(struct gendisk *disk, fmode_t mode) if (disk->flags & (GENHD_FL_NO_PART | GENHD_FL_HIDDEN)) return -EINVAL; + if (test_bit(GD_SUPPRESS_PART_SCAN, &disk->state)) + return -EINVAL; if (disk->open_partitions) return -EBUSY; diff --git a/drivers/block/loop.c b/drivers/block/loop.c index f1dda4ef22cc..084f9b8a0ba3 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1102,7 +1102,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, lo->lo_flags |= LO_FLAGS_PARTSCAN; partscan = lo->lo_flags & LO_FLAGS_PARTSCAN; if (partscan) - lo->lo_disk->flags &= ~GENHD_FL_NO_PART; + clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state); loop_global_unlock(lo, is_loop); if (partscan) @@ -1198,7 +1198,7 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) */ lo->lo_flags = 0; if (!part_shift) - lo->lo_disk->flags |= GENHD_FL_NO_PART; + set_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state); mutex_lock(&lo->lo_mutex); lo->lo_state = Lo_unbound; mutex_unlock(&lo->lo_mutex); @@ -1308,7 +1308,7 @@ out_unfreeze: if (!err && (lo->lo_flags & LO_FLAGS_PARTSCAN) && !(prev_lo_flags & LO_FLAGS_PARTSCAN)) { - lo->lo_disk->flags &= ~GENHD_FL_NO_PART; + clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state); partscan = true; } out_unlock: @@ -2011,7 +2011,7 @@ static int loop_add(int i) * userspace tools. Parameters like this in general should be avoided. */ if (!part_shift) - disk->flags |= GENHD_FL_NO_PART; + set_bit(GD_SUPPRESS_PART_SCAN, &disk->state); mutex_init(&lo->lo_mutex); lo->lo_number = i; spin_lock_init(&lo->lo_lock); diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index ac8b045c777c..07f3c139a3d7 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -403,13 +403,14 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req, if (!mutex_trylock(&cmd->lock)) return BLK_EH_RESET_TIMER; - if (!__test_and_clear_bit(NBD_CMD_INFLIGHT, &cmd->flags)) { + if (!test_bit(NBD_CMD_INFLIGHT, &cmd->flags)) { mutex_unlock(&cmd->lock); return BLK_EH_DONE; } if (!refcount_inc_not_zero(&nbd->config_refs)) { cmd->status = BLK_STS_TIMEOUT; + __clear_bit(NBD_CMD_INFLIGHT, &cmd->flags); mutex_unlock(&cmd->lock); goto done; } @@ -478,6 +479,7 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req, dev_err_ratelimited(nbd_to_dev(nbd), "Connection timed out\n"); set_bit(NBD_RT_TIMEDOUT, &config->runtime_flags); cmd->status = BLK_STS_IOERR; + __clear_bit(NBD_CMD_INFLIGHT, &cmd->flags); mutex_unlock(&cmd->lock); sock_shutdown(nbd); nbd_config_put(nbd); @@ -745,7 +747,7 @@ static struct nbd_cmd *nbd_handle_reply(struct nbd_device *nbd, int index, cmd = blk_mq_rq_to_pdu(req); mutex_lock(&cmd->lock); - if (!__test_and_clear_bit(NBD_CMD_INFLIGHT, &cmd->flags)) { + if (!test_bit(NBD_CMD_INFLIGHT, &cmd->flags)) { dev_err(disk_to_dev(nbd->disk), "Suspicious reply %d (status %u flags %lu)", tag, cmd->status, cmd->flags); ret = -ENOENT; @@ -854,8 +856,16 @@ static void recv_work(struct work_struct *work) } rq = blk_mq_rq_from_pdu(cmd); - if (likely(!blk_should_fake_timeout(rq->q))) - blk_mq_complete_request(rq); + if (likely(!blk_should_fake_timeout(rq->q))) { + bool complete; + + mutex_lock(&cmd->lock); + complete = __test_and_clear_bit(NBD_CMD_INFLIGHT, + &cmd->flags); + mutex_unlock(&cmd->lock); + if (complete) + blk_mq_complete_request(rq); + } percpu_ref_put(&q->q_usage_counter); } @@ -1419,7 +1429,7 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd) static void nbd_clear_sock_ioctl(struct nbd_device *nbd, struct block_device *bdev) { - sock_shutdown(nbd); + nbd_clear_sock(nbd); __invalidate_device(bdev, true); nbd_bdev_reset(nbd); if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF, @@ -1518,15 +1528,20 @@ static struct nbd_config *nbd_alloc_config(void) { struct nbd_config *config; + if (!try_module_get(THIS_MODULE)) + return ERR_PTR(-ENODEV); + config = kzalloc(sizeof(struct nbd_config), GFP_NOFS); - if (!config) - return NULL; + if (!config) { + module_put(THIS_MODULE); + return ERR_PTR(-ENOMEM); + } + atomic_set(&config->recv_threads, 0); init_waitqueue_head(&config->recv_wq); init_waitqueue_head(&config->conn_wait); config->blksize_bits = NBD_DEF_BLKSIZE_BITS; atomic_set(&config->live_connections, 0); - try_module_get(THIS_MODULE); return config; } @@ -1553,12 +1568,13 @@ static int nbd_open(struct block_device *bdev, fmode_t mode) mutex_unlock(&nbd->config_lock); goto out; } - config = nbd->config = nbd_alloc_config(); - if (!config) { - ret = -ENOMEM; + config = nbd_alloc_config(); + if (IS_ERR(config)) { + ret = PTR_ERR(config); mutex_unlock(&nbd->config_lock); goto out; } + nbd->config = config; refcount_set(&nbd->config_refs, 1); refcount_inc(&nbd->refs); mutex_unlock(&nbd->config_lock); @@ -1798,17 +1814,7 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs) refcount_set(&nbd->refs, 0); INIT_LIST_HEAD(&nbd->list); disk->major = NBD_MAJOR; - - /* Too big first_minor can cause duplicate creation of - * sysfs files/links, since index << part_shift might overflow, or - * MKDEV() expect that the max bits of first_minor is 20. - */ disk->first_minor = index << part_shift; - if (disk->first_minor < index || disk->first_minor > MINORMASK) { - err = -EINVAL; - goto out_free_work; - } - disk->minors = 1 << part_shift; disk->fops = &nbd_fops; disk->private_data = nbd; @@ -1913,14 +1919,25 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) if (!netlink_capable(skb, CAP_SYS_ADMIN)) return -EPERM; - if (info->attrs[NBD_ATTR_INDEX]) + if (info->attrs[NBD_ATTR_INDEX]) { index = nla_get_u32(info->attrs[NBD_ATTR_INDEX]); + + /* + * Too big first_minor can cause duplicate creation of + * sysfs files/links, since index << part_shift might overflow, or + * MKDEV() expect that the max bits of first_minor is 20. + */ + if (index < 0 || index > MINORMASK >> part_shift) { + pr_err("illegal input index %d\n", index); + return -EINVAL; + } + } if (!info->attrs[NBD_ATTR_SOCKETS]) { - printk(KERN_ERR "nbd: must specify at least one socket\n"); + pr_err("must specify at least one socket\n"); return -EINVAL; } if (!info->attrs[NBD_ATTR_SIZE_BYTES]) { - printk(KERN_ERR "nbd: must specify a size in bytes for the device\n"); + pr_err("must specify a size in bytes for the device\n"); return -EINVAL; } again: @@ -1956,7 +1973,7 @@ again: nbd_put(nbd); if (index == -1) goto again; - printk(KERN_ERR "nbd: nbd%d already in use\n", index); + pr_err("nbd%d already in use\n", index); return -EBUSY; } if (WARN_ON(nbd->config)) { @@ -1964,13 +1981,14 @@ again: nbd_put(nbd); return -EINVAL; } - config = nbd->config = nbd_alloc_config(); - if (!nbd->config) { + config = nbd_alloc_config(); + if (IS_ERR(config)) { mutex_unlock(&nbd->config_lock); nbd_put(nbd); - printk(KERN_ERR "nbd: couldn't allocate config\n"); - return -ENOMEM; + pr_err("couldn't allocate config\n"); + return PTR_ERR(config); } + nbd->config = config; refcount_set(&nbd->config_refs, 1); set_bit(NBD_RT_BOUND, &config->runtime_flags); @@ -2023,7 +2041,7 @@ again: struct nlattr *socks[NBD_SOCK_MAX+1]; if (nla_type(attr) != NBD_SOCK_ITEM) { - printk(KERN_ERR "nbd: socks must be embedded in a SOCK_ITEM attr\n"); + pr_err("socks must be embedded in a SOCK_ITEM attr\n"); ret = -EINVAL; goto out; } @@ -2032,7 +2050,7 @@ again: nbd_sock_policy, info->extack); if (ret != 0) { - printk(KERN_ERR "nbd: error processing sock list\n"); + pr_err("error processing sock list\n"); ret = -EINVAL; goto out; } @@ -2104,7 +2122,7 @@ static int nbd_genl_disconnect(struct sk_buff *skb, struct genl_info *info) return -EPERM; if (!info->attrs[NBD_ATTR_INDEX]) { - printk(KERN_ERR "nbd: must specify an index to disconnect\n"); + pr_err("must specify an index to disconnect\n"); return -EINVAL; } index = nla_get_u32(info->attrs[NBD_ATTR_INDEX]); @@ -2112,14 +2130,12 @@ static int nbd_genl_disconnect(struct sk_buff *skb, struct genl_info *info) nbd = idr_find(&nbd_index_idr, index); if (!nbd) { mutex_unlock(&nbd_index_mutex); - printk(KERN_ERR "nbd: couldn't find device at index %d\n", - index); + pr_err("couldn't find device at index %d\n", index); return -EINVAL; } if (!refcount_inc_not_zero(&nbd->refs)) { mutex_unlock(&nbd_index_mutex); - printk(KERN_ERR "nbd: device at index %d is going down\n", - index); + pr_err("device at index %d is going down\n", index); return -EINVAL; } mutex_unlock(&nbd_index_mutex); @@ -2144,7 +2160,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info) return -EPERM; if (!info->attrs[NBD_ATTR_INDEX]) { - printk(KERN_ERR "nbd: must specify a device to reconfigure\n"); + pr_err("must specify a device to reconfigure\n"); return -EINVAL; } index = nla_get_u32(info->attrs[NBD_ATTR_INDEX]); @@ -2152,8 +2168,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info) nbd = idr_find(&nbd_index_idr, index); if (!nbd) { mutex_unlock(&nbd_index_mutex); - printk(KERN_ERR "nbd: couldn't find a device at index %d\n", - index); + pr_err("couldn't find a device at index %d\n", index); return -EINVAL; } if (nbd->backend) { @@ -2174,8 +2189,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info) } if (!refcount_inc_not_zero(&nbd->refs)) { mutex_unlock(&nbd_index_mutex); - printk(KERN_ERR "nbd: device at index %d is going down\n", - index); + pr_err("device at index %d is going down\n", index); return -EINVAL; } mutex_unlock(&nbd_index_mutex); @@ -2239,7 +2253,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info) struct nlattr *socks[NBD_SOCK_MAX+1]; if (nla_type(attr) != NBD_SOCK_ITEM) { - printk(KERN_ERR "nbd: socks must be embedded in a SOCK_ITEM attr\n"); + pr_err("socks must be embedded in a SOCK_ITEM attr\n"); ret = -EINVAL; goto out; } @@ -2248,7 +2262,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info) nbd_sock_policy, info->extack); if (ret != 0) { - printk(KERN_ERR "nbd: error processing sock list\n"); + pr_err("error processing sock list\n"); ret = -EINVAL; goto out; } @@ -2465,7 +2479,7 @@ static int __init nbd_init(void) BUILD_BUG_ON(sizeof(struct nbd_request) != 28); if (max_part < 0) { - printk(KERN_ERR "nbd: max_part must be >= 0\n"); + pr_err("max_part must be >= 0\n"); return -EINVAL; } @@ -2528,6 +2542,12 @@ static void __exit nbd_cleanup(void) struct nbd_device *nbd; LIST_HEAD(del_list); + /* + * Unregister netlink interface prior to waiting + * for the completion of netlink commands. + */ + genl_unregister_family(&nbd_genl_family); + nbd_dbg_close(); mutex_lock(&nbd_index_mutex); @@ -2537,8 +2557,11 @@ static void __exit nbd_cleanup(void) while (!list_empty(&del_list)) { nbd = list_first_entry(&del_list, struct nbd_device, list); list_del_init(&nbd->list); + if (refcount_read(&nbd->config_refs)) + pr_err("possibly leaking nbd_config (ref %d)\n", + refcount_read(&nbd->config_refs)); if (refcount_read(&nbd->refs) != 1) - printk(KERN_ERR "nbd: possibly leaking a device\n"); + pr_err("possibly leaking a device\n"); nbd_put(nbd); } @@ -2546,7 +2569,6 @@ static void __exit nbd_cleanup(void) destroy_workqueue(nbd_del_wq); idr_destroy(&nbd_index_idr); - genl_unregister_family(&nbd_genl_family); unregister_blkdev(NBD_MAJOR, "nbd"); } diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 539cfeac263d..6b67088f4ea7 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -77,12 +77,6 @@ enum { NULL_IRQ_TIMER = 2, }; -enum { - NULL_Q_BIO = 0, - NULL_Q_RQ = 1, - NULL_Q_MQ = 2, -}; - static bool g_virt_boundary = false; module_param_named(virt_boundary, g_virt_boundary, bool, 0444); MODULE_PARM_DESC(virt_boundary, "Require a virtual boundary for the device. Default: False"); diff --git a/drivers/block/null_blk/null_blk.h b/drivers/block/null_blk/null_blk.h index 4525a65e1b23..8359b43842f2 100644 --- a/drivers/block/null_blk/null_blk.h +++ b/drivers/block/null_blk/null_blk.h @@ -60,6 +60,13 @@ struct nullb_zone { unsigned int capacity; }; +/* Queue modes */ +enum { + NULL_Q_BIO = 0, + NULL_Q_RQ = 1, + NULL_Q_MQ = 2, +}; + struct nullb_device { struct nullb *nullb; struct config_item item; diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c index ed158ea4fdd1..2fdd7b20c224 100644 --- a/drivers/block/null_blk/zoned.c +++ b/drivers/block/null_blk/zoned.c @@ -398,10 +398,10 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector, */ if (append) { sector = zone->wp; - if (cmd->bio) - cmd->bio->bi_iter.bi_sector = sector; - else + if (dev->queue_mode == NULL_Q_MQ) cmd->rq->__sector = sector; + else + cmd->bio->bi_iter.bi_sector = sector; } else if (sector != zone->wp) { ret = BLK_STS_IOERR; goto unlock; diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index 9ed9c955add7..2acda9cea0f9 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h @@ -395,6 +395,13 @@ struct cached_dev { atomic_t io_errors; unsigned int error_limit; unsigned int offline_seconds; + + /* + * Retry to update writeback_rate if contention happens for + * down_read(dc->writeback_lock) in update_writeback_rate() + */ +#define BCH_WBRATE_UPDATE_MAX_SKIPS 15 + unsigned int rate_update_retry; }; enum alloc_reserve { diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index ad9f16689419..e136d6edc1ed 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -2006,8 +2006,7 @@ int bch_btree_check(struct cache_set *c) int i; struct bkey *k = NULL; struct btree_iter iter; - struct btree_check_state *check_state; - char name[32]; + struct btree_check_state check_state; /* check and mark root node keys */ for_each_key_filter(&c->root->keys, k, &iter, bch_ptr_invalid) @@ -2018,63 +2017,59 @@ int bch_btree_check(struct cache_set *c) if (c->root->level == 0) return 0; - check_state = kzalloc(sizeof(struct btree_check_state), GFP_KERNEL); - if (!check_state) - return -ENOMEM; - - check_state->c = c; - check_state->total_threads = bch_btree_chkthread_nr(); - check_state->key_idx = 0; - spin_lock_init(&check_state->idx_lock); - atomic_set(&check_state->started, 0); - atomic_set(&check_state->enough, 0); - init_waitqueue_head(&check_state->wait); + memset(&check_state, 0, sizeof(struct btree_check_state)); + check_state.c = c; + check_state.total_threads = bch_btree_chkthread_nr(); + check_state.key_idx = 0; + spin_lock_init(&check_state.idx_lock); + atomic_set(&check_state.started, 0); + atomic_set(&check_state.enough, 0); + init_waitqueue_head(&check_state.wait); + rw_lock(0, c->root, c->root->level); /* * Run multiple threads to check btree nodes in parallel, - * if check_state->enough is non-zero, it means current + * if check_state.enough is non-zero, it means current * running check threads are enough, unncessary to create * more. */ - for (i = 0; i < check_state->total_threads; i++) { - /* fetch latest check_state->enough earlier */ + for (i = 0; i < check_state.total_threads; i++) { + /* fetch latest check_state.enough earlier */ smp_mb__before_atomic(); - if (atomic_read(&check_state->enough)) + if (atomic_read(&check_state.enough)) break; - check_state->infos[i].result = 0; - check_state->infos[i].state = check_state; - snprintf(name, sizeof(name), "bch_btrchk[%u]", i); - atomic_inc(&check_state->started); + check_state.infos[i].result = 0; + check_state.infos[i].state = &check_state; - check_state->infos[i].thread = + check_state.infos[i].thread = kthread_run(bch_btree_check_thread, - &check_state->infos[i], - name); - if (IS_ERR(check_state->infos[i].thread)) { + &check_state.infos[i], + "bch_btrchk[%d]", i); + if (IS_ERR(check_state.infos[i].thread)) { pr_err("fails to run thread bch_btrchk[%d]\n", i); for (--i; i >= 0; i--) - kthread_stop(check_state->infos[i].thread); + kthread_stop(check_state.infos[i].thread); ret = -ENOMEM; goto out; } + atomic_inc(&check_state.started); } /* * Must wait for all threads to stop. */ - wait_event_interruptible(check_state->wait, - atomic_read(&check_state->started) == 0); + wait_event(check_state.wait, atomic_read(&check_state.started) == 0); - for (i = 0; i < check_state->total_threads; i++) { - if (check_state->infos[i].result) { - ret = check_state->infos[i].result; + for (i = 0; i < check_state.total_threads; i++) { + if (check_state.infos[i].result) { + ret = check_state.infos[i].result; goto out; } } out: - kfree(check_state); + rw_unlock(0, c->root); return ret; } diff --git a/drivers/md/bcache/btree.h b/drivers/md/bcache/btree.h index 50482107134f..1b5fdbc0d83e 100644 --- a/drivers/md/bcache/btree.h +++ b/drivers/md/bcache/btree.h @@ -226,7 +226,7 @@ struct btree_check_info { int result; }; -#define BCH_BTR_CHKTHREAD_MAX 64 +#define BCH_BTR_CHKTHREAD_MAX 12 struct btree_check_state { struct cache_set *c; int total_threads; diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index df5347ea450b..e5da469a4235 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c @@ -405,6 +405,11 @@ err: return ret; } +void bch_journal_space_reserve(struct journal *j) +{ + j->do_reserve = true; +} + /* Journalling */ static void btree_flush_write(struct cache_set *c) @@ -621,12 +626,30 @@ static void do_journal_discard(struct cache *ca) } } +static unsigned int free_journal_buckets(struct cache_set *c) +{ + struct journal *j = &c->journal; + struct cache *ca = c->cache; + struct journal_device *ja = &c->cache->journal; + unsigned int n; + + /* In case njournal_buckets is not power of 2 */ + if (ja->cur_idx >= ja->discard_idx) + n = ca->sb.njournal_buckets + ja->discard_idx - ja->cur_idx; + else + n = ja->discard_idx - ja->cur_idx; + + if (n > (1 + j->do_reserve)) + return n - (1 + j->do_reserve); + + return 0; +} + static void journal_reclaim(struct cache_set *c) { struct bkey *k = &c->journal.key; struct cache *ca = c->cache; uint64_t last_seq; - unsigned int next; struct journal_device *ja = &ca->journal; atomic_t p __maybe_unused; @@ -649,12 +672,10 @@ static void journal_reclaim(struct cache_set *c) if (c->journal.blocks_free) goto out; - next = (ja->cur_idx + 1) % ca->sb.njournal_buckets; - /* No space available on this device */ - if (next == ja->discard_idx) + if (!free_journal_buckets(c)) goto out; - ja->cur_idx = next; + ja->cur_idx = (ja->cur_idx + 1) % ca->sb.njournal_buckets; k->ptr[0] = MAKE_PTR(0, bucket_to_sector(c, ca->sb.d[ja->cur_idx]), ca->sb.nr_this_dev); diff --git a/drivers/md/bcache/journal.h b/drivers/md/bcache/journal.h index f2ea34d5f431..cd316b4a1e95 100644 --- a/drivers/md/bcache/journal.h +++ b/drivers/md/bcache/journal.h @@ -105,6 +105,7 @@ struct journal { spinlock_t lock; spinlock_t flush_write_lock; bool btree_flushing; + bool do_reserve; /* used when waiting because the journal was full */ struct closure_waitlist wait; struct closure io; @@ -182,5 +183,6 @@ int bch_journal_replay(struct cache_set *c, struct list_head *list); void bch_journal_free(struct cache_set *c); int bch_journal_alloc(struct cache_set *c); +void bch_journal_space_reserve(struct journal *j); #endif /* _BCACHE_JOURNAL_H */ diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 9c5dde73da88..f2c5a7e06fa9 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -1105,6 +1105,12 @@ static void detached_dev_do_request(struct bcache_device *d, struct bio *bio, * which would call closure_get(&dc->disk.cl) */ ddip = kzalloc(sizeof(struct detached_dev_io_private), GFP_NOIO); + if (!ddip) { + bio->bi_status = BLK_STS_RESOURCE; + bio->bi_end_io(bio); + return; + } + ddip->d = d; /* Count on the bcache device */ ddip->orig_bdev = orig_bdev; diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 2f49e31142f6..3563d15dbaf2 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -2127,6 +2127,7 @@ static int run_cache_set(struct cache_set *c) flash_devs_run(c); + bch_journal_space_reserve(&c->journal); set_bit(CACHE_SET_RUNNING, &c->flags); return 0; err: diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c index 9ee0005874cd..3f0ff3aab6f2 100644 --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -235,19 +235,27 @@ static void update_writeback_rate(struct work_struct *work) return; } - if (atomic_read(&dc->has_dirty) && dc->writeback_percent) { - /* - * If the whole cache set is idle, set_at_max_writeback_rate() - * will set writeback rate to a max number. Then it is - * unncessary to update writeback rate for an idle cache set - * in maximum writeback rate number(s). - */ - if (!set_at_max_writeback_rate(c, dc)) { - down_read(&dc->writeback_lock); + /* + * If the whole cache set is idle, set_at_max_writeback_rate() + * will set writeback rate to a max number. Then it is + * unncessary to update writeback rate for an idle cache set + * in maximum writeback rate number(s). + */ + if (atomic_read(&dc->has_dirty) && dc->writeback_percent && + !set_at_max_writeback_rate(c, dc)) { + do { + if (!down_read_trylock((&dc->writeback_lock))) { + dc->rate_update_retry++; + if (dc->rate_update_retry <= + BCH_WBRATE_UPDATE_MAX_SKIPS) + break; + down_read(&dc->writeback_lock); + dc->rate_update_retry = 0; + } __update_writeback_rate(dc); update_gc_after_writeback(c); up_read(&dc->writeback_lock); - } + } while (0); } @@ -805,13 +813,11 @@ static int bch_writeback_thread(void *arg) /* Init */ #define INIT_KEYS_EACH_TIME 500000 -#define INIT_KEYS_SLEEP_MS 100 struct sectors_dirty_init { struct btree_op op; unsigned int inode; size_t count; - struct bkey start; }; static int sectors_dirty_init_fn(struct btree_op *_op, struct btree *b, @@ -827,11 +833,8 @@ static int sectors_dirty_init_fn(struct btree_op *_op, struct btree *b, KEY_START(k), KEY_SIZE(k)); op->count++; - if (atomic_read(&b->c->search_inflight) && - !(op->count % INIT_KEYS_EACH_TIME)) { - bkey_copy_key(&op->start, k); - return -EAGAIN; - } + if (!(op->count % INIT_KEYS_EACH_TIME)) + cond_resched(); return MAP_CONTINUE; } @@ -846,24 +849,16 @@ static int bch_root_node_dirty_init(struct cache_set *c, bch_btree_op_init(&op.op, -1); op.inode = d->id; op.count = 0; - op.start = KEY(op.inode, 0, 0); - - do { - ret = bcache_btree(map_keys_recurse, - k, - c->root, - &op.op, - &op.start, - sectors_dirty_init_fn, - 0); - if (ret == -EAGAIN) - schedule_timeout_interruptible( - msecs_to_jiffies(INIT_KEYS_SLEEP_MS)); - else if (ret < 0) { - pr_warn("sectors dirty init failed, ret=%d!\n", ret); - break; - } - } while (ret == -EAGAIN); + + ret = bcache_btree(map_keys_recurse, + k, + c->root, + &op.op, + &KEY(op.inode, 0, 0), + sectors_dirty_init_fn, + 0); + if (ret < 0) + pr_warn("sectors dirty init failed, ret=%d!\n", ret); return ret; } @@ -907,7 +902,6 @@ static int bch_dirty_init_thread(void *arg) goto out; } skip_nr--; - cond_resched(); } if (p) { @@ -917,7 +911,6 @@ static int bch_dirty_init_thread(void *arg) p = NULL; prev_idx = cur_idx; - cond_resched(); } out: @@ -948,67 +941,56 @@ void bch_sectors_dirty_init(struct bcache_device *d) struct btree_iter iter; struct sectors_dirty_init op; struct cache_set *c = d->c; - struct bch_dirty_init_state *state; - char name[32]; + struct bch_dirty_init_state state; /* Just count root keys if no leaf node */ + rw_lock(0, c->root, c->root->level); if (c->root->level == 0) { bch_btree_op_init(&op.op, -1); op.inode = d->id; op.count = 0; - op.start = KEY(op.inode, 0, 0); for_each_key_filter(&c->root->keys, k, &iter, bch_ptr_invalid) sectors_dirty_init_fn(&op.op, c->root, k); - return; - } - state = kzalloc(sizeof(struct bch_dirty_init_state), GFP_KERNEL); - if (!state) { - pr_warn("sectors dirty init failed: cannot allocate memory\n"); + rw_unlock(0, c->root); return; } - state->c = c; - state->d = d; - state->total_threads = bch_btre_dirty_init_thread_nr(); - state->key_idx = 0; - spin_lock_init(&state->idx_lock); - atomic_set(&state->started, 0); - atomic_set(&state->enough, 0); - init_waitqueue_head(&state->wait); - - for (i = 0; i < state->total_threads; i++) { - /* Fetch latest state->enough earlier */ + memset(&state, 0, sizeof(struct bch_dirty_init_state)); + state.c = c; + state.d = d; + state.total_threads = bch_btre_dirty_init_thread_nr(); + state.key_idx = 0; + spin_lock_init(&state.idx_lock); + atomic_set(&state.started, 0); + atomic_set(&state.enough, 0); + init_waitqueue_head(&state.wait); + + for (i = 0; i < state.total_threads; i++) { + /* Fetch latest state.enough earlier */ smp_mb__before_atomic(); - if (atomic_read(&state->enough)) + if (atomic_read(&state.enough)) break; - state->infos[i].state = state; - atomic_inc(&state->started); - snprintf(name, sizeof(name), "bch_dirty_init[%d]", i); - - state->infos[i].thread = - kthread_run(bch_dirty_init_thread, - &state->infos[i], - name); - if (IS_ERR(state->infos[i].thread)) { + state.infos[i].state = &state; + state.infos[i].thread = + kthread_run(bch_dirty_init_thread, &state.infos[i], + "bch_dirtcnt[%d]", i); + if (IS_ERR(state.infos[i].thread)) { pr_err("fails to run thread bch_dirty_init[%d]\n", i); for (--i; i >= 0; i--) - kthread_stop(state->infos[i].thread); + kthread_stop(state.infos[i].thread); goto out; } + atomic_inc(&state.started); } - /* - * Must wait for all threads to stop. - */ - wait_event_interruptible(state->wait, - atomic_read(&state->started) == 0); - out: - kfree(state); + /* Must wait for all threads to stop. */ + wait_event(state.wait, atomic_read(&state.started) == 0); + rw_unlock(0, c->root); } void bch_cached_dev_writeback_init(struct cached_dev *dc) @@ -1032,6 +1014,9 @@ void bch_cached_dev_writeback_init(struct cached_dev *dc) dc->writeback_rate_fp_term_high = 1000; dc->writeback_rate_i_term_inverse = 10000; + /* For dc->writeback_lock contention in update_writeback_rate() */ + dc->rate_update_retry = 0; + WARN_ON(test_and_clear_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags)); INIT_DELAYED_WORK(&dc->writeback_rate_update, update_writeback_rate); } diff --git a/drivers/md/bcache/writeback.h b/drivers/md/bcache/writeback.h index 02b2f9df73f6..31df716951f6 100644 --- a/drivers/md/bcache/writeback.h +++ b/drivers/md/bcache/writeback.h @@ -20,7 +20,7 @@ #define BCH_WRITEBACK_FRAGMENT_THRESHOLD_MID 57 #define BCH_WRITEBACK_FRAGMENT_THRESHOLD_HIGH 64 -#define BCH_DIRTY_INIT_THRD_MAX 64 +#define BCH_DIRTY_INIT_THRD_MAX 12 /* * 14 (16384ths) is chosen here as something that each backing device * should be a reasonable fraction of the share, and not to blow up diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 9526ccbedafb..5e41fbae3f6b 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -3725,7 +3725,7 @@ static int raid_message(struct dm_target *ti, unsigned int argc, char **argv, if (!strcasecmp(argv[0], "idle") || !strcasecmp(argv[0], "frozen")) { if (mddev->sync_thread) { set_bit(MD_RECOVERY_INTR, &mddev->recovery); - md_reap_sync_thread(mddev); + md_reap_sync_thread(mddev, false); } } else if (decipher_sync_action(mddev, mddev->recovery) != st_idle) return -EBUSY; diff --git a/drivers/md/md-linear.c b/drivers/md/md-linear.c index 138a3b25c5c8..6e7797b4e738 100644 --- a/drivers/md/md-linear.c +++ b/drivers/md/md-linear.c @@ -206,7 +206,6 @@ static void linear_free(struct mddev *mddev, void *priv) static bool linear_make_request(struct mddev *mddev, struct bio *bio) { - char b[BDEVNAME_SIZE]; struct dev_info *tmp_dev; sector_t start_sector, end_sector, data_offset; sector_t bio_sector = bio->bi_iter.bi_sector; @@ -256,10 +255,10 @@ static bool linear_make_request(struct mddev *mddev, struct bio *bio) return true; out_of_bounds: - pr_err("md/linear:%s: make_request: Sector %llu out of bounds on dev %s: %llu sectors, offset %llu\n", + pr_err("md/linear:%s: make_request: Sector %llu out of bounds on dev %pg: %llu sectors, offset %llu\n", mdname(mddev), (unsigned long long)bio->bi_iter.bi_sector, - bdevname(tmp_dev->rdev->bdev, b), + tmp_dev->rdev->bdev, (unsigned long long)tmp_dev->rdev->sectors, (unsigned long long)start_sector); bio_io_error(bio); diff --git a/drivers/md/md-multipath.c b/drivers/md/md-multipath.c index 1c6dbf92c136..66edf5e72bd6 100644 --- a/drivers/md/md-multipath.c +++ b/drivers/md/md-multipath.c @@ -87,10 +87,9 @@ static void multipath_end_request(struct bio *bio) /* * oops, IO error: */ - char b[BDEVNAME_SIZE]; md_error (mp_bh->mddev, rdev); - pr_info("multipath: %s: rescheduling sector %llu\n", - bdevname(rdev->bdev,b), + pr_info("multipath: %pg: rescheduling sector %llu\n", + rdev->bdev, (unsigned long long)bio->bi_iter.bi_sector); multipath_reschedule_retry(mp_bh); } else @@ -154,7 +153,6 @@ static void multipath_status(struct seq_file *seq, struct mddev *mddev) static void multipath_error (struct mddev *mddev, struct md_rdev *rdev) { struct mpconf *conf = mddev->private; - char b[BDEVNAME_SIZE]; if (conf->raid_disks - mddev->degraded <= 1) { /* @@ -177,9 +175,9 @@ static void multipath_error (struct mddev *mddev, struct md_rdev *rdev) } set_bit(Faulty, &rdev->flags); set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags); - pr_err("multipath: IO failure on %s, disabling IO path.\n" + pr_err("multipath: IO failure on %pg, disabling IO path.\n" "multipath: Operation continuing on %d IO paths.\n", - bdevname(rdev->bdev, b), + rdev->bdev, conf->raid_disks - mddev->degraded); } @@ -197,12 +195,11 @@ static void print_multipath_conf (struct mpconf *conf) conf->raid_disks); for (i = 0; i < conf->raid_disks; i++) { - char b[BDEVNAME_SIZE]; tmp = conf->multipaths + i; if (tmp->rdev) - pr_debug(" disk%d, o:%d, dev:%s\n", + pr_debug(" disk%d, o:%d, dev:%pg\n", i,!test_bit(Faulty, &tmp->rdev->flags), - bdevname(tmp->rdev->bdev,b)); + tmp->rdev->bdev); } } 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); diff --git a/drivers/md/md.h b/drivers/md/md.h index cf2cbb17acbd..5f62c46ac2d3 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -719,7 +719,7 @@ extern struct md_thread *md_register_thread( extern void md_unregister_thread(struct md_thread **threadp); extern void md_wakeup_thread(struct md_thread *thread); extern void md_check_recovery(struct mddev *mddev); -extern void md_reap_sync_thread(struct mddev *mddev); +extern void md_reap_sync_thread(struct mddev *mddev, bool reconfig_mutex_held); extern int mddev_init_writes_pending(struct mddev *mddev); extern bool md_write_start(struct mddev *mddev, struct bio *bi); extern void md_write_inc(struct mddev *mddev, struct bio *bi); diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index e11701e394ca..78addfe4a0c9 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -37,7 +37,6 @@ static void dump_zones(struct mddev *mddev) int j, k; sector_t zone_size = 0; sector_t zone_start = 0; - char b[BDEVNAME_SIZE]; struct r0conf *conf = mddev->private; int raid_disks = conf->strip_zone[0].nb_dev; pr_debug("md: RAID0 configuration for %s - %d zone%s\n", @@ -48,9 +47,8 @@ static void dump_zones(struct mddev *mddev) int len = 0; for (k = 0; k < conf->strip_zone[j].nb_dev; k++) - len += snprintf(line+len, 200-len, "%s%s", k?"/":"", - bdevname(conf->devlist[j*raid_disks - + k]->bdev, b)); + len += snprintf(line+len, 200-len, "%s%pg", k?"/":"", + conf->devlist[j * raid_disks + k]->bdev); pr_debug("md: zone%d=[%s]\n", j, line); zone_size = conf->strip_zone[j].zone_end - zone_start; @@ -69,8 +67,6 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) struct md_rdev *smallest, *rdev1, *rdev2, *rdev, **dev; struct strip_zone *zone; int cnt; - char b[BDEVNAME_SIZE]; - char b2[BDEVNAME_SIZE]; struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL); unsigned blksize = 512; @@ -78,9 +74,9 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) if (!conf) return -ENOMEM; rdev_for_each(rdev1, mddev) { - pr_debug("md/raid0:%s: looking at %s\n", + pr_debug("md/raid0:%s: looking at %pg\n", mdname(mddev), - bdevname(rdev1->bdev, b)); + rdev1->bdev); c = 0; /* round size to chunk_size */ @@ -92,12 +88,12 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) rdev1->bdev->bd_disk->queue)); rdev_for_each(rdev2, mddev) { - pr_debug("md/raid0:%s: comparing %s(%llu)" - " with %s(%llu)\n", + pr_debug("md/raid0:%s: comparing %pg(%llu)" + " with %pg(%llu)\n", mdname(mddev), - bdevname(rdev1->bdev,b), + rdev1->bdev, (unsigned long long)rdev1->sectors, - bdevname(rdev2->bdev,b2), + rdev2->bdev, (unsigned long long)rdev2->sectors); if (rdev2 == rdev1) { pr_debug("md/raid0:%s: END\n", @@ -225,15 +221,15 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) for (j=0; j<cnt; j++) { rdev = conf->devlist[j]; if (rdev->sectors <= zone->dev_start) { - pr_debug("md/raid0:%s: checking %s ... nope\n", + pr_debug("md/raid0:%s: checking %pg ... nope\n", mdname(mddev), - bdevname(rdev->bdev, b)); + rdev->bdev); continue; } - pr_debug("md/raid0:%s: checking %s ..." + pr_debug("md/raid0:%s: checking %pg ..." " contained as device %d\n", mdname(mddev), - bdevname(rdev->bdev, b), c); + rdev->bdev, c); dev[c] = rdev; c++; if (!smallest || rdev->sectors < smallest->sectors) { @@ -362,7 +358,6 @@ static void free_conf(struct mddev *mddev, struct r0conf *conf) kfree(conf->strip_zone); kfree(conf->devlist); kfree(conf); - mddev->private = NULL; } static void raid0_free(struct mddev *mddev, void *priv) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 99d5af1362d7..258d4eb2d63c 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -402,10 +402,9 @@ static void raid1_end_read_request(struct bio *bio) /* * oops, read error: */ - char b[BDEVNAME_SIZE]; - pr_err_ratelimited("md/raid1:%s: %s: rescheduling sector %llu\n", + pr_err_ratelimited("md/raid1:%s: %pg: rescheduling sector %llu\n", mdname(conf->mddev), - bdevname(rdev->bdev, b), + rdev->bdev, (unsigned long long)r1_bio->sector); set_bit(R1BIO_ReadError, &r1_bio->state); reschedule_retry(r1_bio); @@ -1283,10 +1282,10 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio, mirror = conf->mirrors + rdisk; if (r1bio_existed) - pr_info_ratelimited("md/raid1:%s: redirecting sector %llu to other mirror: %s\n", + pr_info_ratelimited("md/raid1:%s: redirecting sector %llu to other mirror: %pg\n", mdname(mddev), (unsigned long long)r1_bio->sector, - bdevname(mirror->rdev->bdev, b)); + mirror->rdev->bdev); if (test_bit(WriteMostly, &mirror->rdev->flags) && bitmap) { @@ -1659,7 +1658,6 @@ static void raid1_status(struct seq_file *seq, struct mddev *mddev) */ static void raid1_error(struct mddev *mddev, struct md_rdev *rdev) { - char b[BDEVNAME_SIZE]; struct r1conf *conf = mddev->private; unsigned long flags; @@ -1686,9 +1684,9 @@ static void raid1_error(struct mddev *mddev, struct md_rdev *rdev) set_bit(MD_RECOVERY_INTR, &mddev->recovery); 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" + pr_crit("md/raid1:%s: Disk failure on %pg, disabling device.\n" "md/raid1:%s: Operation continuing on %d devices.\n", - mdname(mddev), bdevname(rdev->bdev, b), + mdname(mddev), rdev->bdev, mdname(mddev), conf->raid_disks - mddev->degraded); } @@ -1706,13 +1704,12 @@ static void print_conf(struct r1conf *conf) rcu_read_lock(); for (i = 0; i < conf->raid_disks; i++) { - char b[BDEVNAME_SIZE]; struct md_rdev *rdev = rcu_dereference(conf->mirrors[i].rdev); if (rdev) - pr_debug(" disk %d, wo:%d, o:%d, dev:%s\n", + pr_debug(" disk %d, wo:%d, o:%d, dev:%pg\n", i, !test_bit(In_sync, &rdev->flags), !test_bit(Faulty, &rdev->flags), - bdevname(rdev->bdev,b)); + rdev->bdev); } rcu_read_unlock(); } @@ -2347,7 +2344,6 @@ static void fix_read_error(struct r1conf *conf, int read_disk, } d = start; while (d != read_disk) { - char b[BDEVNAME_SIZE]; if (d==0) d = conf->raid_disks * 2; d--; @@ -2360,11 +2356,11 @@ static void fix_read_error(struct r1conf *conf, int read_disk, if (r1_sync_page_io(rdev, sect, s, conf->tmppage, READ)) { atomic_add(s, &rdev->corrected_errors); - pr_info("md/raid1:%s: read error corrected (%d sectors at %llu on %s)\n", + pr_info("md/raid1:%s: read error corrected (%d sectors at %llu on %pg)\n", mdname(mddev), s, (unsigned long long)(sect + rdev->data_offset), - bdevname(rdev->bdev, b)); + rdev->bdev); } rdev_dec_pending(rdev, mddev); } else diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index dfa576cdf11c..d589f823feb1 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -397,10 +397,9 @@ static void raid10_end_read_request(struct bio *bio) /* * oops, read error - keep the refcount on the rdev */ - char b[BDEVNAME_SIZE]; - pr_err_ratelimited("md/raid10:%s: %s: rescheduling sector %llu\n", + pr_err_ratelimited("md/raid10:%s: %pg: rescheduling sector %llu\n", mdname(conf->mddev), - bdevname(rdev->bdev, b), + rdev->bdev, (unsigned long long)r10_bio->sector); set_bit(R10BIO_ReadError, &r10_bio->state); reschedule_retry(r10_bio); @@ -1187,9 +1186,9 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio, return; } if (err_rdev) - pr_err_ratelimited("md/raid10:%s: %s: redirecting sector %llu to another mirror\n", + pr_err_ratelimited("md/raid10:%s: %pg: redirecting sector %llu to another mirror\n", mdname(mddev), - bdevname(rdev->bdev, b), + rdev->bdev, (unsigned long long)r10_bio->sector); if (max_sectors < bio_sectors(bio)) { struct bio *split = bio_split(bio, max_sectors, @@ -1987,7 +1986,6 @@ static int enough(struct r10conf *conf, int ignore) */ static void raid10_error(struct mddev *mddev, struct md_rdev *rdev) { - char b[BDEVNAME_SIZE]; struct r10conf *conf = mddev->private; unsigned long flags; @@ -2010,9 +2008,9 @@ static void raid10_error(struct mddev *mddev, struct md_rdev *rdev) 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" + pr_crit("md/raid10:%s: Disk failure on %pg, disabling device.\n" "md/raid10:%s: Operation continuing on %d devices.\n", - mdname(mddev), bdevname(rdev->bdev, b), + mdname(mddev), rdev->bdev, mdname(mddev), conf->geo.raid_disks - mddev->degraded); } @@ -2032,13 +2030,12 @@ static void print_conf(struct r10conf *conf) /* This is only called with ->reconfix_mutex held, so * rcu protection of rdev is not needed */ for (i = 0; i < conf->geo.raid_disks; i++) { - char b[BDEVNAME_SIZE]; rdev = conf->mirrors[i].rdev; if (rdev) - pr_debug(" disk %d, wo:%d, o:%d, dev:%s\n", + pr_debug(" disk %d, wo:%d, o:%d, dev:%pg\n", i, !test_bit(In_sync, &rdev->flags), !test_bit(Faulty, &rdev->flags), - bdevname(rdev->bdev,b)); + rdev->bdev); } } @@ -2691,14 +2688,11 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 check_decay_read_errors(mddev, rdev); atomic_inc(&rdev->read_errors); if (atomic_read(&rdev->read_errors) > max_read_errors) { - char b[BDEVNAME_SIZE]; - bdevname(rdev->bdev, b); - - pr_notice("md/raid10:%s: %s: Raid device exceeded read_error threshold [cur %d:max %d]\n", - mdname(mddev), b, + pr_notice("md/raid10:%s: %pg: Raid device exceeded read_error threshold [cur %d:max %d]\n", + mdname(mddev), rdev->bdev, atomic_read(&rdev->read_errors), max_read_errors); - pr_notice("md/raid10:%s: %s: Failing raid device\n", - mdname(mddev), b); + pr_notice("md/raid10:%s: %pg: Failing raid device\n", + mdname(mddev), rdev->bdev); md_error(mddev, rdev); r10_bio->devs[r10_bio->read_slot].bio = IO_BLOCKED; return; @@ -2768,8 +2762,6 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 /* write it back and re-read */ rcu_read_lock(); while (sl != r10_bio->read_slot) { - char b[BDEVNAME_SIZE]; - if (sl==0) sl = conf->copies; sl--; @@ -2788,24 +2780,22 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 s, conf->tmppage, WRITE) == 0) { /* Well, this device is dead */ - pr_notice("md/raid10:%s: read correction write failed (%d sectors at %llu on %s)\n", + pr_notice("md/raid10:%s: read correction write failed (%d sectors at %llu on %pg)\n", mdname(mddev), s, (unsigned long long)( sect + choose_data_offset(r10_bio, rdev)), - bdevname(rdev->bdev, b)); - pr_notice("md/raid10:%s: %s: failing drive\n", + rdev->bdev); + pr_notice("md/raid10:%s: %pg: failing drive\n", mdname(mddev), - bdevname(rdev->bdev, b)); + rdev->bdev); } rdev_dec_pending(rdev, mddev); rcu_read_lock(); } sl = start; while (sl != r10_bio->read_slot) { - char b[BDEVNAME_SIZE]; - if (sl==0) sl = conf->copies; sl--; @@ -2825,23 +2815,23 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 READ)) { case 0: /* Well, this device is dead */ - pr_notice("md/raid10:%s: unable to read back corrected sectors (%d sectors at %llu on %s)\n", + pr_notice("md/raid10:%s: unable to read back corrected sectors (%d sectors at %llu on %pg)\n", mdname(mddev), s, (unsigned long long)( sect + choose_data_offset(r10_bio, rdev)), - bdevname(rdev->bdev, b)); - pr_notice("md/raid10:%s: %s: failing drive\n", + rdev->bdev); + pr_notice("md/raid10:%s: %pg: failing drive\n", mdname(mddev), - bdevname(rdev->bdev, b)); + rdev->bdev); break; case 1: - pr_info("md/raid10:%s: read error corrected (%d sectors at %llu on %s)\n", + pr_info("md/raid10:%s: read error corrected (%d sectors at %llu on %pg)\n", mdname(mddev), s, (unsigned long long)( sect + choose_data_offset(r10_bio, rdev)), - bdevname(rdev->bdev, b)); + rdev->bdev); atomic_add(s, &rdev->corrected_errors); } diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 094a4042589e..83c184eddbda 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -3064,11 +3064,10 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev) { struct request_queue *q = bdev_get_queue(rdev->bdev); struct r5l_log *log; - char b[BDEVNAME_SIZE]; int ret; - pr_debug("md/raid:%s: using device %s as journal\n", - mdname(conf->mddev), bdevname(rdev->bdev, b)); + pr_debug("md/raid:%s: using device %pg as journal\n", + mdname(conf->mddev), rdev->bdev); if (PAGE_SIZE != 4096) return -EINVAL; diff --git a/drivers/md/raid5-ppl.c b/drivers/md/raid5-ppl.c index 55d065a87b89..973e2e06f19c 100644 --- a/drivers/md/raid5-ppl.c +++ b/drivers/md/raid5-ppl.c @@ -798,7 +798,6 @@ static int ppl_recover_entry(struct ppl_log *log, struct ppl_header_entry *e, int data_disks; int i; int ret = 0; - char b[BDEVNAME_SIZE]; unsigned int pp_size = le32_to_cpu(e->pp_size); unsigned int data_size = le32_to_cpu(e->data_size); @@ -894,8 +893,8 @@ static int ppl_recover_entry(struct ppl_log *log, struct ppl_header_entry *e, break; } - pr_debug("%s:%*s reading data member disk %s sector %llu\n", - __func__, indent, "", bdevname(rdev->bdev, b), + pr_debug("%s:%*s reading data member disk %pg sector %llu\n", + __func__, indent, "", rdev->bdev, (unsigned long long)sector); if (!sync_page_io(rdev, sector, block_size, page2, REQ_OP_READ, 0, false)) { @@ -942,10 +941,10 @@ static int ppl_recover_entry(struct ppl_log *log, struct ppl_header_entry *e, conf->disks[sh.pd_idx].rdev, 1); BUG_ON(parity_rdev->bdev->bd_dev != log->rdev->bdev->bd_dev); - pr_debug("%s:%*s write parity at sector %llu, disk %s\n", + pr_debug("%s:%*s write parity at sector %llu, disk %pg\n", __func__, indent, "", (unsigned long long)parity_sector, - bdevname(parity_rdev->bdev, b)); + parity_rdev->bdev); if (!sync_page_io(parity_rdev, parity_sector, block_size, page1, REQ_OP_WRITE, 0, false)) { pr_debug("%s:%*s parity write error!\n", __func__, @@ -1255,7 +1254,6 @@ void ppl_exit_log(struct r5conf *conf) static int ppl_validate_rdev(struct md_rdev *rdev) { - char b[BDEVNAME_SIZE]; int ppl_data_sectors; int ppl_size_new; @@ -1272,8 +1270,8 @@ static int ppl_validate_rdev(struct md_rdev *rdev) RAID5_STRIPE_SECTORS((struct r5conf *)rdev->mddev->private)); if (ppl_data_sectors <= 0) { - pr_warn("md/raid:%s: PPL space too small on %s\n", - mdname(rdev->mddev), bdevname(rdev->bdev, b)); + pr_warn("md/raid:%s: PPL space too small on %pg\n", + mdname(rdev->mddev), rdev->bdev); return -ENOSPC; } @@ -1283,16 +1281,16 @@ static int ppl_validate_rdev(struct md_rdev *rdev) rdev->ppl.sector + ppl_size_new > rdev->data_offset) || (rdev->ppl.sector >= rdev->data_offset && rdev->data_offset + rdev->sectors > rdev->ppl.sector)) { - pr_warn("md/raid:%s: PPL space overlaps with data on %s\n", - mdname(rdev->mddev), bdevname(rdev->bdev, b)); + pr_warn("md/raid:%s: PPL space overlaps with data on %pg\n", + mdname(rdev->mddev), rdev->bdev); return -EINVAL; } if (!rdev->mddev->external && ((rdev->ppl.offset > 0 && rdev->ppl.offset < (rdev->sb_size >> 9)) || (rdev->ppl.offset <= 0 && rdev->ppl.offset + ppl_size_new > 0))) { - pr_warn("md/raid:%s: PPL space overlaps with superblock on %s\n", - mdname(rdev->mddev), bdevname(rdev->bdev, b)); + pr_warn("md/raid:%s: PPL space overlaps with superblock on %pg\n", + mdname(rdev->mddev), rdev->bdev); return -EINVAL; } @@ -1463,14 +1461,13 @@ int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add) struct ppl_conf *ppl_conf = conf->log_private; struct ppl_log *log; int ret = 0; - char b[BDEVNAME_SIZE]; if (!rdev) return -EINVAL; - pr_debug("%s: disk: %d operation: %s dev: %s\n", + pr_debug("%s: disk: %d operation: %s dev: %pg\n", __func__, rdev->raid_disk, add ? "add" : "remove", - bdevname(rdev->bdev, b)); + rdev->bdev); if (rdev->raid_disk < 0) return 0; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 39038fa8b1c8..5d09256d7f81 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2686,7 +2686,6 @@ static void raid5_end_read_request(struct bio * bi) struct stripe_head *sh = bi->bi_private; struct r5conf *conf = sh->raid_conf; int disks = sh->disks, i; - char b[BDEVNAME_SIZE]; struct md_rdev *rdev = NULL; sector_t s; @@ -2723,10 +2722,10 @@ static void raid5_end_read_request(struct bio * bi) * any error */ pr_info_ratelimited( - "md/raid:%s: read error corrected (%lu sectors at %llu on %s)\n", + "md/raid:%s: read error corrected (%lu sectors at %llu on %pg)\n", mdname(conf->mddev), RAID5_STRIPE_SECTORS(conf), (unsigned long long)s, - bdevname(rdev->bdev, b)); + rdev->bdev); atomic_add(RAID5_STRIPE_SECTORS(conf), &rdev->corrected_errors); clear_bit(R5_ReadError, &sh->dev[i].flags); clear_bit(R5_ReWrite, &sh->dev[i].flags); @@ -2743,7 +2742,6 @@ static void raid5_end_read_request(struct bio * bi) if (atomic_read(&rdev->read_errors)) atomic_set(&rdev->read_errors, 0); } else { - const char *bdn = bdevname(rdev->bdev, b); int retry = 0; int set_bad = 0; @@ -2752,25 +2750,25 @@ static void raid5_end_read_request(struct bio * bi) atomic_inc(&rdev->read_errors); if (test_bit(R5_ReadRepl, &sh->dev[i].flags)) pr_warn_ratelimited( - "md/raid:%s: read error on replacement device (sector %llu on %s).\n", + "md/raid:%s: read error on replacement device (sector %llu on %pg).\n", mdname(conf->mddev), (unsigned long long)s, - bdn); + rdev->bdev); else if (conf->mddev->degraded >= conf->max_degraded) { set_bad = 1; pr_warn_ratelimited( - "md/raid:%s: read error not correctable (sector %llu on %s).\n", + "md/raid:%s: read error not correctable (sector %llu on %pg).\n", mdname(conf->mddev), (unsigned long long)s, - bdn); + rdev->bdev); } else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) { /* Oh, no!!! */ set_bad = 1; pr_warn_ratelimited( - "md/raid:%s: read error NOT corrected!! (sector %llu on %s).\n", + "md/raid:%s: read error NOT corrected!! (sector %llu on %pg).\n", mdname(conf->mddev), (unsigned long long)s, - bdn); + rdev->bdev); } else if (atomic_read(&rdev->read_errors) > conf->max_nr_stripes) { if (!test_bit(Faulty, &rdev->flags)) { @@ -2778,8 +2776,8 @@ static void raid5_end_read_request(struct bio * bi) mdname(conf->mddev), atomic_read(&rdev->read_errors), conf->max_nr_stripes); - pr_warn("md/raid:%s: Too many read errors, failing device %s.\n", - mdname(conf->mddev), bdn); + pr_warn("md/raid:%s: Too many read errors, failing device %pg.\n", + mdname(conf->mddev), rdev->bdev); } } else retry = 1; @@ -2891,13 +2889,12 @@ static void raid5_end_write_request(struct bio *bi) static void raid5_error(struct mddev *mddev, struct md_rdev *rdev) { - char b[BDEVNAME_SIZE]; struct r5conf *conf = mddev->private; unsigned long flags; pr_debug("raid456: error called\n"); - pr_crit("md/raid:%s: Disk failure on %s, disabling device.\n", - mdname(mddev), bdevname(rdev->bdev, b)); + pr_crit("md/raid:%s: Disk failure on %pg, disabling device.\n", + mdname(mddev), rdev->bdev); spin_lock_irqsave(&conf->device_lock, flags); set_bit(Faulty, &rdev->flags); @@ -7359,9 +7356,8 @@ static struct r5conf *setup_conf(struct mddev *mddev) } if (test_bit(In_sync, &rdev->flags)) { - char b[BDEVNAME_SIZE]; - pr_info("md/raid:%s: device %s operational as raid disk %d\n", - mdname(mddev), bdevname(rdev->bdev, b), raid_disk); + pr_info("md/raid:%s: device %pg operational as raid disk %d\n", + mdname(mddev), rdev->bdev, raid_disk); } else if (rdev->saved_raid_disk != raid_disk) /* Cannot rely on bitmap to complete recovery */ conf->fullsync = 1; @@ -7877,12 +7873,11 @@ static void print_raid5_conf (struct r5conf *conf) rcu_read_lock(); for (i = 0; i < conf->raid_disks; i++) { - char b[BDEVNAME_SIZE]; rdev = rcu_dereference(conf->disks[i].rdev); if (rdev) - pr_debug(" disk %d, o:%d, dev:%s\n", + pr_debug(" disk %d, o:%d, dev:%pg\n", i, !test_bit(Faulty, &rdev->flags), - bdevname(rdev->bdev, b)); + rdev->bdev); } rcu_read_unlock(); } diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 727c12cbe327..24165daee3c8 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2228,8 +2228,16 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl) ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE; ctrl->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES; - ctrl->ctrl_config |= NVME_CC_ENABLE; + ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config); + if (ret) + return ret; + /* Flush write to device (required if transport is PCI) */ + ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CC, &ctrl->ctrl_config); + if (ret) + return ret; + + ctrl->ctrl_config |= NVME_CC_ENABLE; ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config); if (ret) return ret; diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 0403b6d10bb4..48f4f6eb877b 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3457,6 +3457,8 @@ static const struct pci_device_id nvme_id_table[] = { .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, + { PCI_DEVICE(0x1e4B, 0x1001), /* MAXIO MAP1001 */ + .driver_data = NVME_QUIRK_BOGUS_NID, }, { PCI_DEVICE(0x1e4B, 0x1002), /* MAXIO MAP1002 */ .driver_data = NVME_QUIRK_BOGUS_NID, }, { PCI_DEVICE(0x1e4B, 0x1202), /* MAXIO MAP1202 */ diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c index 3cc4d6709c93..b1f7efab3918 100644 --- a/drivers/nvme/target/passthru.c +++ b/drivers/nvme/target/passthru.c @@ -97,7 +97,7 @@ static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req) id->sgls |= cpu_to_le32(1 << 20); /* - * When passsthru controller is setup using nvme-loop transport it will + * When passthru controller is setup using nvme-loop transport it will * export the passthru ctrl subsysnqn (PCIe NVMe ctrl) and will fail in * the nvme/host/core.c in the nvme_init_subsystem()->nvme_active_ctrl() * code path with duplicate ctr subsynqn. In order to prevent that we diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 1b24c1fb3bb1..608d577734c2 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -147,6 +147,7 @@ struct gendisk { #define GD_DEAD 2 #define GD_NATIVE_CAPACITY 3 #define GD_ADDED 4 +#define GD_SUPPRESS_PART_SCAN 5 struct mutex open_mutex; /* open/close mutex */ unsigned open_partitions; /* number of open partitions */ |