Merge tag 'for-6.9/block-20240310' of git://git.kernel.dk/linux
[linux-2.6-microblaze.git] / drivers / block / nbd.c
index 33a8f37..9d4ec92 100644 (file)
@@ -316,9 +316,12 @@ static void nbd_mark_nsock_dead(struct nbd_device *nbd, struct nbd_sock *nsock,
        nsock->sent = 0;
 }
 
-static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize,
+static int __nbd_set_size(struct nbd_device *nbd, loff_t bytesize,
                loff_t blksize)
 {
+       struct queue_limits lim;
+       int error;
+
        if (!blksize)
                blksize = 1u << NBD_DEF_BLKSIZE_BITS;
 
@@ -334,10 +337,16 @@ static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize,
        if (!nbd->pid)
                return 0;
 
+       lim = queue_limits_start_update(nbd->disk->queue);
        if (nbd->config->flags & NBD_FLAG_SEND_TRIM)
-               blk_queue_max_discard_sectors(nbd->disk->queue, UINT_MAX);
-       blk_queue_logical_block_size(nbd->disk->queue, blksize);
-       blk_queue_physical_block_size(nbd->disk->queue, blksize);
+               lim.max_hw_discard_sectors = UINT_MAX;
+       else
+               lim.max_hw_discard_sectors = 0;
+       lim.logical_block_size = blksize;
+       lim.physical_block_size = blksize;
+       error = queue_limits_commit_update(nbd->disk->queue, &lim);
+       if (error)
+               return error;
 
        if (max_part)
                set_bit(GD_NEED_PART_SCAN, &nbd->disk->state);
@@ -346,6 +355,18 @@ static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize,
        return 0;
 }
 
+static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize,
+               loff_t blksize)
+{
+       int error;
+
+       blk_mq_freeze_queue(nbd->disk->queue);
+       error = __nbd_set_size(nbd, bytesize, blksize);
+       blk_mq_unfreeze_queue(nbd->disk->queue);
+
+       return error;
+}
+
 static void nbd_complete_rq(struct request *req)
 {
        struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req);
@@ -1351,7 +1372,6 @@ static void nbd_config_put(struct nbd_device *nbd)
                nbd->config = NULL;
 
                nbd->tag_set.timeout = 0;
-               blk_queue_max_discard_sectors(nbd->disk->queue, 0);
 
                mutex_unlock(&nbd->config_lock);
                nbd_put(nbd);
@@ -1783,6 +1803,12 @@ static const struct blk_mq_ops nbd_mq_ops = {
 
 static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
 {
+       struct queue_limits lim = {
+               .max_hw_sectors         = 65536,
+               .max_user_sectors       = 256,
+               .max_segments           = USHRT_MAX,
+               .max_segment_size       = UINT_MAX,
+       };
        struct nbd_device *nbd;
        struct gendisk *disk;
        int err = -ENOMEM;
@@ -1823,7 +1849,7 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
        if (err < 0)
                goto out_free_tags;
 
-       disk = blk_mq_alloc_disk(&nbd->tag_set, NULL);
+       disk = blk_mq_alloc_disk(&nbd->tag_set, &lim, NULL);
        if (IS_ERR(disk)) {
                err = PTR_ERR(disk);
                goto out_free_idr;
@@ -1843,11 +1869,6 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
         * Tell the block layer that we are not a rotational device
         */
        blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue);
-       blk_queue_max_discard_sectors(disk->queue, 0);
-       blk_queue_max_segment_size(disk->queue, UINT_MAX);
-       blk_queue_max_segments(disk->queue, USHRT_MAX);
-       blk_queue_max_hw_sectors(disk->queue, 65536);
-       disk->queue->limits.max_sectors = 256;
 
        mutex_init(&nbd->config_lock);
        refcount_set(&nbd->config_refs, 0);
@@ -2433,6 +2454,12 @@ static int nbd_genl_status(struct sk_buff *skb, struct genl_info *info)
        }
 
        dev_list = nla_nest_start_noflag(reply, NBD_ATTR_DEVICE_LIST);
+       if (!dev_list) {
+               nlmsg_free(reply);
+               ret = -EMSGSIZE;
+               goto out;
+       }
+
        if (index == -1) {
                ret = idr_for_each(&nbd_index_idr, &status_cb, reply);
                if (ret) {