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