Re: [syzbot] [block?] INFO: task hung in bdev_release

From: syzbot
Date: Fri Dec 15 2023 - 23:18:05 EST


For archival purposes, forwarding an incoming command email to
linux-kernel@xxxxxxxxxxxxxxx.

***

Subject: [block?] INFO: task hung in bdev_release
Author: eadavis@xxxxxx

please test task hung in bdev_release

#syz test https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git 8c9660f65153

diff --git a/block/bdev.c b/block/bdev.c
index 6f73b02d549c..17ead61b00e2 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -854,6 +854,7 @@ struct bdev_handle *bdev_open_by_dev(dev_t dev, blk_mode_t mode, void *holder,

disk_block_events(disk);

+ printk("next om, b: %p, disk: %p, %s\n", bdev, disk, __func__);
mutex_lock(&disk->open_mutex);
ret = -ENXIO;
if (!disk_live(disk))
@@ -887,6 +888,7 @@ struct bdev_handle *bdev_open_by_dev(dev_t dev, blk_mode_t mode, void *holder,
}
}
mutex_unlock(&disk->open_mutex);
+ printk("out om, b: %p, disk: %p, %s\n", bdev, disk, __func__);

if (unblock_events)
disk_unblock_events(disk);
@@ -900,6 +902,7 @@ struct bdev_handle *bdev_open_by_dev(dev_t dev, blk_mode_t mode, void *holder,
if (holder)
bd_abort_claiming(bdev, holder);
mutex_unlock(&disk->open_mutex);
+ printk("out om, b: %p, %s\n", bdev, __func__);
disk_unblock_events(disk);
put_blkdev:
blkdev_put_no_open(bdev);
@@ -964,6 +967,7 @@ void bdev_release(struct bdev_handle *handle)
if (atomic_read(&bdev->bd_openers) == 1)
sync_blockdev(bdev);

+ printk("nxt om, b: %p, dk: %p, %s\n", bdev, disk, __func__);
mutex_lock(&disk->open_mutex);
bdev_yield_write_access(bdev, handle->mode);

@@ -982,6 +986,7 @@ void bdev_release(struct bdev_handle *handle)
else
blkdev_put_whole(bdev);
mutex_unlock(&disk->open_mutex);
+ printk("out om, b: %p, dk: %p, %s\n", bdev, disk, __func__);

module_put(disk->fops->owner);
blkdev_put_no_open(bdev);
diff --git a/block/ioctl.c b/block/ioctl.c
index 9c73a763ef88..67825e6bec13 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -483,6 +483,7 @@ static int blkdev_bszset(struct block_device *bdev, blk_mode_t mode,
if (mode & BLK_OPEN_EXCL)
return set_blocksize(bdev, n);

+ printk("s: %d, b: %p, bd: %p, %s\n", n, bdev, bdev->bd_dev, __func__);
handle = bdev_open_by_dev(bdev->bd_dev, mode, &bdev, NULL);
if (IS_ERR(handle))
return -EBUSY;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index b6414e1e645b..3cc7993b0b67 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -1137,6 +1137,7 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
int err;

/* Arg will be cast to int, check it to avoid overflow */
+ printk("arg: %d, nbd: %p, %s\n", arg, nbd, __func__);
if (arg > INT_MAX)
return -EINVAL;
sock = nbd_get_socket(nbd, arg, &err);
@@ -1188,10 +1189,12 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
socks[config->num_connections++] = nsock;
atomic_inc(&config->live_connections);
blk_mq_unfreeze_queue(nbd->disk->queue);
+ printk("arg: %d, nbd: %p, nd: %p, nc: %d, %s\n", arg, nbd, nbd->disk, config->num_connections, __func__);

return 0;

put_socket:
+ printk("nbd: %p, %s\n", nbd, __func__);
blk_mq_unfreeze_queue(nbd->disk->queue);
sockfd_put(sock);
return err;
@@ -1372,6 +1375,7 @@ static int nbd_start_device(struct nbd_device *nbd)
int num_connections = config->num_connections;
int error = 0, i;

+ printk("dev: %p, nc: %d, pid: %d, socks: %p, %s\n", nbd, num_connections, nbd->pid, config->socks, __func__);
if (nbd->pid)
return -EBUSY;
if (!config->socks)
@@ -1425,6 +1429,7 @@ static int nbd_start_device(struct nbd_device *nbd)
args->index = i;
queue_work(nbd->recv_workq, &args->work);
}
+ printk("bs: %lld, blks: %lld, %s\n", config->bytesize, nbd_blksize(config), __func__);
return nbd_set_size(nbd, config->bytesize, nbd_blksize(config));
}