Re: [PATCH v5 5/8] nbd: skip queue freeze when setting size at device startup

"yu kuai" <[email protected]> Sun, 2 Aug 2026 19:45:01 +0800
Newsgroups org.kernel.vger.linux-block
Message-ID <[email protected]>
Hi,

=E5=9C=A8 2026/7/30 16:20, Yang Erkun =E5=86=99=E9=81=93:
> Commit 242a49e5c878 ("nbd: freeze the queue for queue limits updates")
> added the freeze to keep in-flight commands from seeing torn
> queue_limits.  But at startup the capacity is still 0
> (invalidate_disk cleared it) and the write cache is off (the previous
> patch cleared it on disconnect, and nbd_set_size sets it back only after
> the commit), so submit_bio_noacct() rejects any bio before it reaches
> the driver and no I/O is in flight.  Drop the freeze there.
>
> Split nbd_set_size() with a bool: nbd_start_device() passes false, the
> runtime resize/reconfigure paths (ioctls and nbd_genl_size_set) keep
> passing true.  nbd->pid is still 0 when nbd_genl_connect calls
> nbd_genl_size_set, so the early return in nbd_set_size keeps that path
> from applying limits before startup; the true covers the reconnect path
> on a live device.
>
> Signed-off-by: Yang Erkun <[email protected]>
> ---
>   drivers/block/nbd.c | 21 ++++++++++++++-------
>   1 file changed, 14 insertions(+), 7 deletions(-)

Can you just checking if size is 0 and write cache is disabled first, and j=
ust
skip freeze in this case. I think this is simpler and straightforward, as y=
ou
don't have to modify all the callers.

>
> diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
> index ce25c254e5fb..3b7363b11d0b 100644
> --- a/drivers/block/nbd.c
> +++ b/drivers/block/nbd.c
> @@ -331,7 +331,8 @@ static void nbd_mark_nsock_dead(struct nbd_device *nb=
d, struct nbd_sock *nsock,
>   	nsock->sent =3D 0;
>   }
>  =20
> -static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize, loff_t =
blksize)
> +static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize, loff_t =
blksize,
> +			bool freeze)
>   {
>   	struct queue_limits lim;
>   	int error;
> @@ -371,7 +372,13 @@ static int nbd_set_size(struct nbd_device *nbd, loff=
_t bytesize, loff_t blksize)
>  =20
>   	lim.logical_block_size =3D blksize;
>   	lim.physical_block_size =3D blksize;
> -	error =3D queue_limits_commit_update_frozen(nbd->disk->queue, &lim);
> +
> +	if (freeze)
> +		error =3D queue_limits_commit_update_frozen(nbd->disk->queue,
> +				&lim);
> +	else
> +		error =3D queue_limits_commit_update(nbd->disk->queue, &lim);
> +
>   	if (error)
>   		return error;
>  =20
> @@ -1568,7 +1575,7 @@ static int nbd_start_device(struct nbd_device *nbd)
>   		args->index =3D i;
>   		queue_work(nbd->recv_workq, &args->work);
>   	}
> -	return nbd_set_size(nbd, config->bytesize, nbd_blksize(config));
> +	return nbd_set_size(nbd, config->bytesize, nbd_blksize(config), false);
>   }
>  =20
>   static int nbd_start_device_ioctl(struct nbd_device *nbd)
> @@ -1636,13 +1643,13 @@ static int __nbd_ioctl(struct block_device *bdev,=
 struct nbd_device *nbd,
>   	case NBD_SET_SOCK:
>   		return nbd_add_socket(nbd, arg, false);
>   	case NBD_SET_BLKSIZE:
> -		return nbd_set_size(nbd, config->bytesize, arg);
> +		return nbd_set_size(nbd, config->bytesize, arg, true);
>   	case NBD_SET_SIZE:
> -		return nbd_set_size(nbd, arg, nbd_blksize(config));
> +		return nbd_set_size(nbd, arg, nbd_blksize(config), true);
>   	case NBD_SET_SIZE_BLOCKS:
>   		if (check_shl_overflow(arg, config->blksize_bits, &bytesize))
>   			return -EINVAL;
> -		return nbd_set_size(nbd, bytesize, nbd_blksize(config));
> +		return nbd_set_size(nbd, bytesize, nbd_blksize(config), true);
>   	case NBD_SET_TIMEOUT:
>   		nbd_set_cmd_timeout(nbd, arg);
>   		return 0;
> @@ -2097,7 +2104,7 @@ static int nbd_genl_size_set(struct genl_info *info=
, struct nbd_device *nbd)
>   		bsize =3D nla_get_u64(info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]);
>  =20
>   	if (bytes !=3D config->bytesize || bsize !=3D nbd_blksize(config))
> -		return nbd_set_size(nbd, bytes, bsize);
> +		return nbd_set_size(nbd, bytes, bsize, true);
>   	return 0;
>   }
>  =20

--=20
Thanks,
Kuai