diff mbox series

ublk: add timeout handler

Message ID 20230502010150.878696-1-ming.lei@redhat.com (mailing list archive)
State New, archived
Headers show
Series ublk: add timeout handler | expand

Commit Message

Ming Lei May 2, 2023, 1:01 a.m. UTC
Add timeout handler, so that we can provide forward progress guarantee for
unprivileged ublk, which can't be trusted.

One thing is that sync() calls sync_bdevs(wait) for all block devices after
running sync_bdevs(no_wait), and if one device can't move on, the sync() won't
return any more.

Add timeout for unprivileged ublk to avoid such affect for other users which call
sync() syscall.

Fixes: 4093cb5a0634 ("ublk_drv: add mechanism for supporting unprivileged ublk device")
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 drivers/block/ublk_drv.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Ming Lei May 2, 2023, 1:15 a.m. UTC | #1
On Tue, May 02, 2023 at 09:01:50AM +0800, Ming Lei wrote:
> Add timeout handler, so that we can provide forward progress guarantee for
> unprivileged ublk, which can't be trusted.
> 
> One thing is that sync() calls sync_bdevs(wait) for all block devices after
> running sync_bdevs(no_wait), and if one device can't move on, the sync() won't
> return any more.
> 
> Add timeout for unprivileged ublk to avoid such affect for other users which call
> sync() syscall.
> 

We need to clear UBLK_F_USER_RECOVERY_REISSUE for unprivileged ublk,
please ignore this patch, and will send V2.


Thanks,
Ming
diff mbox series

Patch

diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index afbef182820b..50f5e5abd721 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -129,6 +129,7 @@  struct ublk_queue {
 	unsigned long io_addr;	/* mapped vm address */
 	unsigned int max_io_sz;
 	bool force_abort;
+	bool timeout;
 	unsigned short nr_io_ready;	/* how many ios setup */
 	struct ublk_device *dev;
 	struct ublk_io ios[];
@@ -898,6 +899,22 @@  static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq)
 	}
 }
 
+static enum blk_eh_timer_return ublk_timeout(struct request *rq)
+{
+	struct ublk_queue *ubq = rq->mq_hctx->driver_data;
+
+	if (ubq->flags & UBLK_F_UNPRIVILEGED_DEV) {
+		if (!ubq->timeout) {
+			send_sig(SIGKILL, ubq->ubq_daemon, 0);
+			ubq->timeout = true;
+		}
+
+		return BLK_EH_DONE;
+	}
+
+	return BLK_EH_RESET_TIMER;
+}
+
 static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx,
 		const struct blk_mq_queue_data *bd)
 {
@@ -957,6 +974,7 @@  static const struct blk_mq_ops ublk_mq_ops = {
 	.queue_rq       = ublk_queue_rq,
 	.init_hctx	= ublk_init_hctx,
 	.init_request   = ublk_init_rq,
+	.timeout	= ublk_timeout,
 };
 
 static int ublk_ch_open(struct inode *inode, struct file *filp)