Commit 78c6499c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
  ...
parents 72fbbc3d aacae8c4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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;

+4 −4
Original line number Diff line number Diff line
@@ -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 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)

	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);
+68 −46
Original line number Diff line number Diff line
@@ -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)))
		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 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
		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 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
		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 @@ static int nbd_genl_connect(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;
			}
@@ -2032,7 +2050,7 @@ static int nbd_genl_connect(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;
			}
@@ -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");
}

+0 −6
Original line number Diff line number Diff line
@@ -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");
+7 −0
Original line number Diff line number Diff line
@@ -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;
Loading