From 0471c6fe24a3bc1c12cf2dbf0efd7056a1f9fe0c Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Thu, 19 Nov 2020 14:48:25 +0800 Subject: [PATCH] nbd: don't update block size after device is started mainline inclusion from mainline-v5.10-rc2 commit b40813ddcd6b category: bugfix bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1891363 CVE: NA backport: openEuler-20.09 Here is the testcase: 1. rbd create --size 2G rbdpool/foo 2. rbd-nbd map rbdpool/foo 3. mkfs.ext4 /dev/nbd0 4. mount /dev/nbd0 /mnt 5. rbd resize --size 4G rbdpool/foo 6. ls /mnt ls will stuck here forever. -------------------------------- Mounted NBD device can be resized, one use case is rbd-nbd. Fix the issue by setting up default block size, then not touch it in nbd_size_update() any more. This kind of usage is aligned with loop which has same use case too. Cc: stable@vger.kernel.org Fixes: c8a83a6b54d0 ("nbd: Use set_blocksize() to set device blocksize") Reported-by: lining Signed-off-by: Ming Lei Cc: Josef Bacik Cc: Jan Kara Tested-by: lining Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Signed-off-by: lining Reviewed-by: Xie XiuQi Signed-off-by: Yang Yingliang --- drivers/block/nbd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 8a4df4a9bca8..292129174c38 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -293,7 +293,7 @@ static void nbd_size_clear(struct nbd_device *nbd) } } -static void nbd_size_update(struct nbd_device *nbd) +static void nbd_size_update(struct nbd_device *nbd, bool start) { struct nbd_config *config = nbd->config; struct block_device *bdev = bdget_disk(nbd->disk, 0); @@ -309,7 +309,8 @@ static void nbd_size_update(struct nbd_device *nbd) if (bdev) { if (bdev->bd_disk) { bd_set_size(bdev, config->bytesize); - set_blocksize(bdev, config->blksize); + if (start) + set_blocksize(bdev, config->blksize); } else bdev->bd_invalidated = 1; bdput(bdev); @@ -324,7 +325,7 @@ static void nbd_size_set(struct nbd_device *nbd, loff_t blocksize, config->blksize = blocksize; config->bytesize = blocksize * nr_blocks; if (nbd->task_recv != NULL) - nbd_size_update(nbd); + nbd_size_update(nbd, false); } static void nbd_complete_rq(struct request *req) @@ -1248,7 +1249,7 @@ static int nbd_start_device(struct nbd_device *nbd) args->index = i; queue_work(nbd->recv_workq, &args->work); } - nbd_size_update(nbd); + nbd_size_update(nbd, true); return error; } -- GitLab