From patchwork Wed Mar 16 08:45:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12782445 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EB317C433F5 for ; Wed, 16 Mar 2022 08:45:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354621AbiCPIqr (ORCPT ); Wed, 16 Mar 2022 04:46:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37930 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232210AbiCPIqp (ORCPT ); Wed, 16 Mar 2022 04:46:45 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 89F2763BFA for ; Wed, 16 Mar 2022 01:45:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=WlHTgA/IPa/9lZDoaOPinCl4gzMoMfO9tBqmnB3Opms=; b=32y2/0sOdYsEZn8WCBNEodIbqF 54uetPuO7XotiJSQKpjyJyw0wp4/vpkkjcJSN8SfY+SW7p/2/oVrw6toloqhbulvPRdww8DPXFr+O E6TGC45mmWnql6nzDs8PZRoRbIHotHoClYCr90B/ZxuGsRGZDe7QNhRhFLSGAtpIiHBTtzgISNyzb uTGqWQT4k+xoAuRu1+u2nG4Yie7NDLYKxr2aUCzjugZdrDj93rPhZHbUNzEDLn/Lm8EfVZ6S+jQhD ZHwxyULtkijpi48nZFwwBryRJeoBrK+qQ0h+494girHt99PITCovoUVQqb9shSjCWl9kjuwzen336 hyRTsQpA==; Received: from [46.140.54.162] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1nUPHY-00CC8V-UL; Wed, 16 Mar 2022 08:45:25 +0000 From: Christoph Hellwig To: Jens Axboe Cc: Tetsuo Handa , Jan Kara , "Darrick J . Wong" , linux-block@vger.kernel.org, Ming Lei Subject: [PATCH 1/8] loop: de-duplicate the idle worker freeing code Date: Wed, 16 Mar 2022 09:45:12 +0100 Message-Id: <20220316084519.2850118-2-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220316084519.2850118-1-hch@lst.de> References: <20220316084519.2850118-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Use a common helper for both timer based and uncoditional freeing of idle workers. Signed-off-by: Christoph Hellwig Reviewed-by: Jan Kara Tested-by: Darrick J. Wong --- drivers/block/loop.c | 73 +++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 08f7772bb5261..64227e659efc4 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -809,7 +809,6 @@ struct loop_worker { static void loop_workfn(struct work_struct *work); static void loop_rootcg_workfn(struct work_struct *work); -static void loop_free_idle_workers(struct timer_list *timer); #ifdef CONFIG_BLK_CGROUP static inline int queue_on_root_worker(struct cgroup_subsys_state *css) @@ -893,6 +892,39 @@ static void loop_queue_work(struct loop_device *lo, struct loop_cmd *cmd) spin_unlock_irq(&lo->lo_work_lock); } +static void loop_set_timer(struct loop_device *lo) +{ + timer_reduce(&lo->timer, jiffies + LOOP_IDLE_WORKER_TIMEOUT); +} + +static void loop_free_idle_workers(struct loop_device *lo, bool delete_all) +{ + struct loop_worker *pos, *worker; + + spin_lock_irq(&lo->lo_work_lock); + list_for_each_entry_safe(worker, pos, &lo->idle_worker_list, + idle_list) { + if (!delete_all && + time_is_after_jiffies(worker->last_ran_at + + LOOP_IDLE_WORKER_TIMEOUT)) + break; + list_del(&worker->idle_list); + rb_erase(&worker->rb_node, &lo->worker_tree); + css_put(worker->blkcg_css); + kfree(worker); + } + if (!list_empty(&lo->idle_worker_list)) + loop_set_timer(lo); + spin_unlock_irq(&lo->lo_work_lock); +} + +static void loop_free_idle_workers_timer(struct timer_list *timer) +{ + struct loop_device *lo = container_of(timer, struct loop_device, timer); + + return loop_free_idle_workers(lo, false); +} + static void loop_update_rotational(struct loop_device *lo) { struct file *file = lo->lo_backing_file; @@ -1027,7 +1059,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, INIT_LIST_HEAD(&lo->rootcg_cmd_list); INIT_LIST_HEAD(&lo->idle_worker_list); lo->worker_tree = RB_ROOT; - timer_setup(&lo->timer, loop_free_idle_workers, + timer_setup(&lo->timer, loop_free_idle_workers_timer, TIMER_DEFERRABLE); lo->use_dio = lo->lo_flags & LO_FLAGS_DIRECT_IO; lo->lo_device = bdev; @@ -1091,7 +1123,6 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) { struct file *filp; gfp_t gfp = lo->old_gfp_mask; - struct loop_worker *pos, *worker; /* * Flush loop_configure() and loop_change_fd(). It is acceptable for @@ -1121,15 +1152,7 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) blk_mq_freeze_queue(lo->lo_queue); destroy_workqueue(lo->workqueue); - spin_lock_irq(&lo->lo_work_lock); - list_for_each_entry_safe(worker, pos, &lo->idle_worker_list, - idle_list) { - list_del(&worker->idle_list); - rb_erase(&worker->rb_node, &lo->worker_tree); - css_put(worker->blkcg_css); - kfree(worker); - } - spin_unlock_irq(&lo->lo_work_lock); + loop_free_idle_workers(lo, true); del_timer_sync(&lo->timer); spin_lock_irq(&lo->lo_lock); @@ -1887,11 +1910,6 @@ static void loop_handle_cmd(struct loop_cmd *cmd) } } -static void loop_set_timer(struct loop_device *lo) -{ - timer_reduce(&lo->timer, jiffies + LOOP_IDLE_WORKER_TIMEOUT); -} - static void loop_process_work(struct loop_worker *worker, struct list_head *cmd_list, struct loop_device *lo) { @@ -1940,27 +1958,6 @@ static void loop_rootcg_workfn(struct work_struct *work) loop_process_work(NULL, &lo->rootcg_cmd_list, lo); } -static void loop_free_idle_workers(struct timer_list *timer) -{ - struct loop_device *lo = container_of(timer, struct loop_device, timer); - struct loop_worker *pos, *worker; - - spin_lock_irq(&lo->lo_work_lock); - list_for_each_entry_safe(worker, pos, &lo->idle_worker_list, - idle_list) { - if (time_is_after_jiffies(worker->last_ran_at + - LOOP_IDLE_WORKER_TIMEOUT)) - break; - list_del(&worker->idle_list); - rb_erase(&worker->rb_node, &lo->worker_tree); - css_put(worker->blkcg_css); - kfree(worker); - } - if (!list_empty(&lo->idle_worker_list)) - loop_set_timer(lo); - spin_unlock_irq(&lo->lo_work_lock); -} - static const struct blk_mq_ops loop_mq_ops = { .queue_rq = loop_queue_rq, .complete = lo_complete_rq, From patchwork Wed Mar 16 08:45:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12782444 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9442DC433FE for ; Wed, 16 Mar 2022 08:45:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354615AbiCPIqr (ORCPT ); Wed, 16 Mar 2022 04:46:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37936 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354595AbiCPIqp (ORCPT ); Wed, 16 Mar 2022 04:46:45 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 147F964BD7 for ; Wed, 16 Mar 2022 01:45:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=G/i2VL4ZSrXtxk8zMKc9LlK7I2p8DCMTRMVUqNb3p6Q=; b=MwJTlvsrdITMs0uPh4xl/aoZtW j42Mg4+aRF0NgTJKGYs3fTq0eWNk6XkJPh5tHFqm8zKHh8BcNbCisbpcXJAn2CPAj1kIu6rIUTGI0 g1WStyR/Q/kWyBpeoNmXN09gHx5cV4uNigwR2LPnRU/lYrndB4dtV67VU0eMEK8C7gpUe8UhNB+JO gzChj1BPAG6R7KW1YLD5F9YnAV9h4hyvT8JVp5QhIpkfoXV3BrI8AWIFtKY6EbDswYim5drdbHVK9 ELFlJiMdzyVBsPdfVFnLEkx3Ac10j+GkLk6fPghHK36JAkS4d8vWTe1FxZ/aC/CZo4xGhHQx58st8 /eNAudAQ==; Received: from [46.140.54.162] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1nUPHb-00CC9y-P9; Wed, 16 Mar 2022 08:45:28 +0000 From: Christoph Hellwig To: Jens Axboe Cc: Tetsuo Handa , Jan Kara , "Darrick J . Wong" , linux-block@vger.kernel.org, Ming Lei Subject: [PATCH 2/8] loop: initialize the worker tracking fields once Date: Wed, 16 Mar 2022 09:45:13 +0100 Message-Id: <20220316084519.2850118-3-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220316084519.2850118-1-hch@lst.de> References: <20220316084519.2850118-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org There is no need to reinitialize idle_worker_list, worker_tree and timer every time a loop device is configured. Just initialize them once at allocation time. Signed-off-by: Christoph Hellwig Reviewed-by: Jan Kara Tested-by: Darrick J. Wong Reviewed-by: Chaitanya Kulkarni --- drivers/block/loop.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 64227e659efc4..2d344fefda6b8 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1057,10 +1057,6 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, INIT_WORK(&lo->rootcg_work, loop_rootcg_workfn); INIT_LIST_HEAD(&lo->rootcg_cmd_list); - INIT_LIST_HEAD(&lo->idle_worker_list); - lo->worker_tree = RB_ROOT; - timer_setup(&lo->timer, loop_free_idle_workers_timer, - TIMER_DEFERRABLE); lo->use_dio = lo->lo_flags & LO_FLAGS_DIRECT_IO; lo->lo_device = bdev; lo->lo_backing_file = file; @@ -1973,6 +1969,9 @@ static int loop_add(int i) lo = kzalloc(sizeof(*lo), GFP_KERNEL); if (!lo) goto out; + lo->worker_tree = RB_ROOT; + INIT_LIST_HEAD(&lo->idle_worker_list); + timer_setup(&lo->timer, loop_free_idle_workers_timer, TIMER_DEFERRABLE); lo->lo_state = Lo_unbound; err = mutex_lock_killable(&loop_ctl_mutex); From patchwork Wed Mar 16 08:45:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12782446 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1659FC4332F for ; Wed, 16 Mar 2022 08:45:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354617AbiCPIqt (ORCPT ); Wed, 16 Mar 2022 04:46:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38004 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354595AbiCPIqs (ORCPT ); Wed, 16 Mar 2022 04:46:48 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C72B264BD7 for ; Wed, 16 Mar 2022 01:45:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=DUmrrWpDIgVSlj8a/27oSUPz+jLHXhALNhViz2nDfYY=; b=4lGo5Z2pw2EVW1JSDp/4GYHdWW WwewE5/K0QAI47C/AWVTN+hWiRZ3XG3dnO3BHsQMK3rO2Ruf5cpfl9txFkZiWvN0FlSL1PpXF8ndL 1191UseV6eMKAgBySzMYqnUqyKy0uzgAYWDJqG1JjE1xhfQEZFYhVB1Vnz7QCjVCI1P8orfBZTaSK zJy7oUuCxvhpBlu7xTpRii26DjPywEe3vgfdMJR/upw9puFdtWKq9bwT6gR4Ax92sKVK5x/MZ2p0s u9TnHq1NhnBGGK77pksvNvg1nCzR/GyWGbRfMeNO/dXmzV9bJrfRGHs1X7urES9beUpE5ac+VijaX OtQQGw+Q==; Received: from [46.140.54.162] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1nUPHe-00CCBM-O6; Wed, 16 Mar 2022 08:45:31 +0000 From: Christoph Hellwig To: Jens Axboe Cc: Tetsuo Handa , Jan Kara , "Darrick J . Wong" , linux-block@vger.kernel.org, Ming Lei Subject: [PATCH 3/8] loop: remove the racy bd_inode->i_mapping->nrpages asserts Date: Wed, 16 Mar 2022 09:45:14 +0100 Message-Id: <20220316084519.2850118-4-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220316084519.2850118-1-hch@lst.de> References: <20220316084519.2850118-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Nothing prevents a file system or userspace opener of the block device from redirtying the page right afte sync_blockdev returned. Fortunately data in the page cache during a block device change is mostly harmless anyway. Signed-off-by: Christoph Hellwig Tested-by: Darrick J. Wong Reviewed-by: Jan Kara --- drivers/block/loop.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 2d344fefda6b8..e3361c6b22150 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1276,15 +1276,6 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) /* I/O need to be drained during transfer transition */ blk_mq_freeze_queue(lo->lo_queue); - if (size_changed && lo->lo_device->bd_inode->i_mapping->nrpages) { - /* If any pages were dirtied after invalidate_bdev(), try again */ - err = -EAGAIN; - pr_warn("%s: loop%d (%s) still has dirty pages (nrpages=%lu)\n", - __func__, lo->lo_number, lo->lo_file_name, - lo->lo_device->bd_inode->i_mapping->nrpages); - goto out_unfreeze; - } - prev_lo_flags = lo->lo_flags; err = loop_set_status_from_info(lo, info); @@ -1495,21 +1486,10 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg) invalidate_bdev(lo->lo_device); blk_mq_freeze_queue(lo->lo_queue); - - /* invalidate_bdev should have truncated all the pages */ - if (lo->lo_device->bd_inode->i_mapping->nrpages) { - err = -EAGAIN; - pr_warn("%s: loop%d (%s) still has dirty pages (nrpages=%lu)\n", - __func__, lo->lo_number, lo->lo_file_name, - lo->lo_device->bd_inode->i_mapping->nrpages); - goto out_unfreeze; - } - blk_queue_logical_block_size(lo->lo_queue, arg); blk_queue_physical_block_size(lo->lo_queue, arg); blk_queue_io_min(lo->lo_queue, arg); loop_update_dio(lo); -out_unfreeze: blk_mq_unfreeze_queue(lo->lo_queue); return err; From patchwork Wed Mar 16 08:45:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12782447 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E10FDC433F5 for ; Wed, 16 Mar 2022 08:45:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232210AbiCPIqv (ORCPT ); Wed, 16 Mar 2022 04:46:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38040 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348751AbiCPIqu (ORCPT ); Wed, 16 Mar 2022 04:46:50 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8790E64BD1 for ; Wed, 16 Mar 2022 01:45:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=R0FK3mzMobKYU6iSMO3tDE5ai7szZ2Nwhxp/sFGZ6ME=; b=yZIzEQphrqWnKV+XEBrXxmO4/n KfQDkark6gRAC3PTR3rhxXK7Ud4/Nv2iZAE2K47Z05YSADijQs/faKuNk/fcSDSvGOgvFcCBaJQS3 AUaUXMYynJqp60QiJeJhK6G9ZBY5w9OFuigxQGtf9VTYaFFLscJ0BvUh3rDDcAUyMPLquKA/9XYYz gvr1XIESsWpySLr7dnxIrHkCY6pZv1uO3EWmkzTXqcKvqGTM7zUGkd2cG1x/0PkVyUkjKr1/aDop7 9b6ehi/n/T+Ye887c9tgw7Bqq7k/wRknhkTNya/yD7Sg81GSbX496Y9DfWFElx7V2zDota4bm793a 90Y0MB4A==; Received: from [46.140.54.162] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1nUPHh-00CCCT-MD; Wed, 16 Mar 2022 08:45:34 +0000 From: Christoph Hellwig To: Jens Axboe Cc: Tetsuo Handa , Jan Kara , "Darrick J . Wong" , linux-block@vger.kernel.org, Ming Lei Subject: [PATCH 4/8] loop: don't freeze the queue in lo_release Date: Wed, 16 Mar 2022 09:45:15 +0100 Message-Id: <20220316084519.2850118-5-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220316084519.2850118-1-hch@lst.de> References: <20220316084519.2850118-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org By the time the final ->release is called there can't be outstanding I/O. For non-final ->release there is no need for driver action at all. Thus remove the useless queue freeze. Signed-off-by: Christoph Hellwig Reviewed-by: Jan Kara Tested-by: Darrick J. Wong --- drivers/block/loop.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index e3361c6b22150..87d77464c2800 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1753,13 +1753,6 @@ static void lo_release(struct gendisk *disk, fmode_t mode) */ __loop_clr_fd(lo, true); return; - } else if (lo->lo_state == Lo_bound) { - /* - * Otherwise keep thread (if running) and config, - * but flush possible ongoing bios in thread. - */ - blk_mq_freeze_queue(lo->lo_queue); - blk_mq_unfreeze_queue(lo->lo_queue); } out_unlock: From patchwork Wed Mar 16 08:45:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12782448 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5D33C433EF for ; Wed, 16 Mar 2022 08:45:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354622AbiCPIqy (ORCPT ); Wed, 16 Mar 2022 04:46:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348751AbiCPIqy (ORCPT ); Wed, 16 Mar 2022 04:46:54 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 08FAA63BFA for ; Wed, 16 Mar 2022 01:45:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=TVeULILu8PMsbwhGhGxYFfPqdzCYqm7aQtjL1Sj6jzY=; b=zRWq90vYZpZFgHvVWmn6ZWwV0s 2pTLGBa7HNmUYOHXQS3g5m2PawKU3VQnWnL6sDHp+oWx/YP0NVEIxCpNZd4naytl1rPrlJ5q4Y50g mFMJH54Zb1hN4r4rW1nBnwWynuzx0DIH4h2KPcazZGG9U1lnRGGbQnIBDo+qKW3CK5yxapzIqbmmZ nO8fBhVa0ZS60Yr1OnsRCaPYd0EllGMQ5XdarOttIIAEH/Fv/1WBuyjvZ6eosbGeUcLjxJdUuBu2B 9hixU0My3WckF+9GX54FvGueaR9OjaWjxny16lI5ZMNlVc4XaWNiyOfpBUfIe5h3uGzuma+ncGi3N liKFisRw==; Received: from [46.140.54.162] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1nUPHk-00CCDY-FZ; Wed, 16 Mar 2022 08:45:36 +0000 From: Christoph Hellwig To: Jens Axboe Cc: Tetsuo Handa , Jan Kara , "Darrick J . Wong" , linux-block@vger.kernel.org, Ming Lei Subject: [PATCH 5/8] loop: only freeze the queue in __loop_clr_fd when needed Date: Wed, 16 Mar 2022 09:45:16 +0100 Message-Id: <20220316084519.2850118-6-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220316084519.2850118-1-hch@lst.de> References: <20220316084519.2850118-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org ->release is only called after all outstanding I/O has completed, so only freeze the queue when clearing the backing file of a live loop device. Signed-off-by: Christoph Hellwig Reviewed-by: Jan Kara Tested-by: Darrick J. Wong --- drivers/block/loop.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 87d77464c2800..0813f63d5bbd2 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1144,8 +1144,13 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) if (test_bit(QUEUE_FLAG_WC, &lo->lo_queue->queue_flags)) blk_queue_write_cache(lo->lo_queue, false, false); - /* freeze request queue during the transition */ - blk_mq_freeze_queue(lo->lo_queue); + /* + * Freeze the request queue when unbinding on a live file descriptor and + * thus an open device. When called from ->release we are guaranteed + * that there is no I/O in progress already. + */ + if (!release) + blk_mq_freeze_queue(lo->lo_queue); destroy_workqueue(lo->workqueue); loop_free_idle_workers(lo, true); @@ -1170,7 +1175,8 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) mapping_set_gfp_mask(filp->f_mapping, gfp); /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); - blk_mq_unfreeze_queue(lo->lo_queue); + if (!release) + blk_mq_unfreeze_queue(lo->lo_queue); disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE); From patchwork Wed Mar 16 08:45:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12782449 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 119D1C433F5 for ; Wed, 16 Mar 2022 08:45:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354595AbiCPIq6 (ORCPT ); Wed, 16 Mar 2022 04:46:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38170 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354620AbiCPIq6 (ORCPT ); Wed, 16 Mar 2022 04:46:58 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3196264BE4 for ; Wed, 16 Mar 2022 01:45:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=wG748xja2qha/1f4Jrn2/OTebVsKlo5KlY91E/Gevs8=; b=HCgK6cSUBgs+0lVtKCAVamt/el FS81Q2mnNH09U+ibJRvlfrLM1dznfx8OvpWmnahb3IDxG2curGIKVvENU4svrD7LhJHyP1JrSJ4zl LqqfVzdXSGvx6H6vIHwKo+RZZgW/fEzd6gSQRJcKQO2Qxy561+fF+3lfufTcLnaL8w8vTAMZSL0xH BNlmem7azFhKHT/cifHqn3Cn1g424k2ZCurBV7U2ZeWBOZstgkxHYUa4A66yYaXjMkSZjsmCVHy+n e+TJ6WoL2SB3U/t/27zFWzDkNxidF8PhgGrhxoe4BOjHqWT4NHKCcmlscfhXFFcrwdtK9uuWn94uq kL3Q5/Eg==; Received: from [46.140.54.162] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1nUPHn-00CCFX-Bq; Wed, 16 Mar 2022 08:45:39 +0000 From: Christoph Hellwig To: Jens Axboe Cc: Tetsuo Handa , Jan Kara , "Darrick J . Wong" , linux-block@vger.kernel.org, Ming Lei Subject: [PATCH 6/8] loop: implement ->free_disk Date: Wed, 16 Mar 2022 09:45:17 +0100 Message-Id: <20220316084519.2850118-7-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220316084519.2850118-1-hch@lst.de> References: <20220316084519.2850118-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Ensure that the lo_device which is stored in the gendisk private data is valid until the gendisk is freed. Currently the loop driver uses a lot of effort to make sure a device is not freed when it is still in use, but to to fix a potential deadlock this will be relaxed a bit soon. Signed-off-by: Christoph Hellwig Reviewed-by: Jan Kara --- drivers/block/loop.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 0813f63d5bbd2..cbaa18bcad1fe 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1765,6 +1765,14 @@ static void lo_release(struct gendisk *disk, fmode_t mode) mutex_unlock(&lo->lo_mutex); } +static void lo_free_disk(struct gendisk *disk) +{ + struct loop_device *lo = disk->private_data; + + mutex_destroy(&lo->lo_mutex); + kfree(lo); +} + static const struct block_device_operations lo_fops = { .owner = THIS_MODULE, .open = lo_open, @@ -1773,6 +1781,7 @@ static const struct block_device_operations lo_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = lo_compat_ioctl, #endif + .free_disk = lo_free_disk, }; /* @@ -2064,14 +2073,13 @@ static void loop_remove(struct loop_device *lo) { /* Make this loop device unreachable from pathname. */ del_gendisk(lo->lo_disk); - blk_cleanup_disk(lo->lo_disk); + blk_cleanup_queue(lo->lo_disk->queue); blk_mq_free_tag_set(&lo->tag_set); mutex_lock(&loop_ctl_mutex); idr_remove(&loop_index_idr, lo->lo_number); mutex_unlock(&loop_ctl_mutex); - /* There is no route which can find this loop device. */ - mutex_destroy(&lo->lo_mutex); - kfree(lo); + + put_disk(lo->lo_disk); } static void loop_probe(dev_t dev) From patchwork Wed Mar 16 08:45:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12782450 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8BAD5C433EF for ; Wed, 16 Mar 2022 08:45:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348751AbiCPIrA (ORCPT ); Wed, 16 Mar 2022 04:47:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38202 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354624AbiCPIq7 (ORCPT ); Wed, 16 Mar 2022 04:46:59 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6EEBC63BFA for ; Wed, 16 Mar 2022 01:45:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=VytvXi/ofTXtBnUa851r1k2mUlJR5hNmhRa8J5sSdpE=; b=UcI8b2vXWChXCkQyh3fotWCxgu NGA1gv3IAmM/dPfG2TeYI7lcsruJ/2VPmb/wXPYi81J2hrcp9IV5n9UNJ6a5o68Zs0TF0KRZoZUWk M9Jnv/ajN5se4XC6ZpOxFMqlX1kOmxpgP8EMDFBLgbjVMpNlDuxLR5j8VHIQaZ6rYmBmk+U4LSWgS G8QosajCQaD8HztNbz85sbCNyreQ8Mf0xocDXymfllh9izX+xjUA47axpol5XqWsxbhHPH8wFtZMI kWivDuVAj6nzxT4/b+9lsYqZwm4FUBxzP9zAs9kK0RNLeBXyBUwUSEXG5hqDnxTyR4im6J17/I3jC gZhH4tGA==; Received: from [46.140.54.162] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1nUPHq-00CCH8-Dl; Wed, 16 Mar 2022 08:45:42 +0000 From: Christoph Hellwig To: Jens Axboe Cc: Tetsuo Handa , Jan Kara , "Darrick J . Wong" , linux-block@vger.kernel.org, Ming Lei Subject: [PATCH 7/8] loop: remove lo_refcount and avoid lo_mutex in ->open / ->release Date: Wed, 16 Mar 2022 09:45:18 +0100 Message-Id: <20220316084519.2850118-8-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220316084519.2850118-1-hch@lst.de> References: <20220316084519.2850118-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org lo_refcount counts how many openers a loop device has, but that count is already provided by the block layer in the bd_openers field of the whole-disk block_device. Remove lo_refcount and allow opens to succeed even on devices beeing deleted - now that ->free_disk is implemented we can handle that race gracefull and all I/O on it will just fail. Similarly there is a small race window now where loop_control_remove does not synchronize the delete vs the remove due do bd_openers not being under lo_mutex protection, but we can handle that just as gracefully. Signed-off-by: Christoph Hellwig --- drivers/block/loop.c | 36 +++++++----------------------------- drivers/block/loop.h | 1 - 2 files changed, 7 insertions(+), 30 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index cbaa18bcad1fe..c270f3715d829 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1244,7 +1244,7 @@ static int loop_clr_fd(struct loop_device *lo) * /do something like mkfs/losetup -d causing the losetup -d * command to fail with EBUSY. */ - if (atomic_read(&lo->lo_refcnt) > 1) { + if (lo->lo_disk->part0->bd_openers > 1) { lo->lo_flags |= LO_FLAGS_AUTOCLEAR; mutex_unlock(&lo->lo_mutex); return 0; @@ -1724,33 +1724,15 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, } #endif -static int lo_open(struct block_device *bdev, fmode_t mode) -{ - struct loop_device *lo = bdev->bd_disk->private_data; - int err; - - err = mutex_lock_killable(&lo->lo_mutex); - if (err) - return err; - if (lo->lo_state == Lo_deleting) - err = -ENXIO; - else - atomic_inc(&lo->lo_refcnt); - mutex_unlock(&lo->lo_mutex); - return err; -} - static void lo_release(struct gendisk *disk, fmode_t mode) { struct loop_device *lo = disk->private_data; - mutex_lock(&lo->lo_mutex); - if (atomic_dec_return(&lo->lo_refcnt)) - goto out_unlock; + if (disk->part0->bd_openers > 0) + return; - if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) { - if (lo->lo_state != Lo_bound) - goto out_unlock; + mutex_lock(&lo->lo_mutex); + if (lo->lo_state == Lo_bound && (lo->lo_flags & LO_FLAGS_AUTOCLEAR)) { lo->lo_state = Lo_rundown; mutex_unlock(&lo->lo_mutex); /* @@ -1760,8 +1742,6 @@ static void lo_release(struct gendisk *disk, fmode_t mode) __loop_clr_fd(lo, true); return; } - -out_unlock: mutex_unlock(&lo->lo_mutex); } @@ -1775,7 +1755,6 @@ static void lo_free_disk(struct gendisk *disk) static const struct block_device_operations lo_fops = { .owner = THIS_MODULE, - .open = lo_open, .release = lo_release, .ioctl = lo_ioctl, #ifdef CONFIG_COMPAT @@ -2029,7 +2008,6 @@ static int loop_add(int i) */ if (!part_shift) disk->flags |= GENHD_FL_NO_PART; - atomic_set(&lo->lo_refcnt, 0); mutex_init(&lo->lo_mutex); lo->lo_number = i; spin_lock_init(&lo->lo_lock); @@ -2119,12 +2097,12 @@ static int loop_control_remove(int idx) if (ret) goto mark_visible; if (lo->lo_state != Lo_unbound || - atomic_read(&lo->lo_refcnt) > 0) { + lo->lo_disk->part0->bd_openers > 0) { mutex_unlock(&lo->lo_mutex); ret = -EBUSY; goto mark_visible; } - /* Mark this loop device no longer open()-able. */ + /* Mark this loop device as no more bound, but not quite unbound yet */ lo->lo_state = Lo_deleting; mutex_unlock(&lo->lo_mutex); diff --git a/drivers/block/loop.h b/drivers/block/loop.h index 082d4b6bfc6a6..449d562738c52 100644 --- a/drivers/block/loop.h +++ b/drivers/block/loop.h @@ -28,7 +28,6 @@ struct loop_func_table; struct loop_device { int lo_number; - atomic_t lo_refcnt; loff_t lo_offset; loff_t lo_sizelimit; int lo_flags; From patchwork Wed Mar 16 08:45:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12782451 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4A725C433EF for ; Wed, 16 Mar 2022 08:45:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354632AbiCPIrE (ORCPT ); Wed, 16 Mar 2022 04:47:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354627AbiCPIrD (ORCPT ); Wed, 16 Mar 2022 04:47:03 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 429A463BFB for ; Wed, 16 Mar 2022 01:45:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=ElK6DPhqE0Oj8jmV2s8FSaguDMVHjao6McD2FDCKrfE=; b=X8wSJ6JhnZIMNqhRzSFR2c4Kyn 0ocFR7uoseqLFFNH9bdHPPq5s+86yprEQkudTsTjKpTduQHdCqgRDqsZg6xaY2Lo7QDz3pN3UsZtz 2nDnNetcLrx9KaQmCbHknf4LfJH/RsSaA9uvJu2GpaJOgecnDGtgFt7YxS1AdFqbExxQyHnV5blTt QygFtGny3ByQpg/HUIzbS9Tt0cxFdet+BeeKNXYyedCsQjTHmLMy69j6AVlmEOdjeEnCdscSWyL4U NP5iML+oeLqikYQMGMEIHLbnokAgXJB32gk+mEIxnSR+raaeCPY2yKGehAUmfVyh2L5Hof32O9Uew FzQLbkXg==; Received: from [46.140.54.162] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1nUPHt-00CCIi-JZ; Wed, 16 Mar 2022 08:45:46 +0000 From: Christoph Hellwig To: Jens Axboe Cc: Tetsuo Handa , Jan Kara , "Darrick J . Wong" , linux-block@vger.kernel.org, Ming Lei , syzbot+6479585dfd4dedd3f7e1@syzkaller.appspotmail.com Subject: [PATCH 8/8] loop: don't destroy lo->workqueue in __loop_clr_fd Date: Wed, 16 Mar 2022 09:45:19 +0100 Message-Id: <20220316084519.2850118-9-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220316084519.2850118-1-hch@lst.de> References: <20220316084519.2850118-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org There is no need to destroy the workqueue when clearing unbinding a loop device from a backing file. Not doing so on the other hand avoid creating a complex lock dependency chain involving the global system_transition_mutex. Based on a patch from Tetsuo Handa . Reported-by: syzbot+6479585dfd4dedd3f7e1@syzkaller.appspotmail.com Signed-off-by: Christoph Hellwig Reviewed-by: Jan Kara --- drivers/block/loop.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index c270f3715d829..ffc9f00c433cd 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -808,7 +808,6 @@ struct loop_worker { }; static void loop_workfn(struct work_struct *work); -static void loop_rootcg_workfn(struct work_struct *work); #ifdef CONFIG_BLK_CGROUP static inline int queue_on_root_worker(struct cgroup_subsys_state *css) @@ -1043,20 +1042,19 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, !file->f_op->write_iter) lo->lo_flags |= LO_FLAGS_READ_ONLY; - lo->workqueue = alloc_workqueue("loop%d", - WQ_UNBOUND | WQ_FREEZABLE, - 0, - lo->lo_number); if (!lo->workqueue) { - error = -ENOMEM; - goto out_unlock; + lo->workqueue = alloc_workqueue("loop%d", + WQ_UNBOUND | WQ_FREEZABLE, + 0, lo->lo_number); + if (!lo->workqueue) { + error = -ENOMEM; + goto out_unlock; + } } disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE); set_disk_ro(lo->lo_disk, (lo->lo_flags & LO_FLAGS_READ_ONLY) != 0); - INIT_WORK(&lo->rootcg_work, loop_rootcg_workfn); - INIT_LIST_HEAD(&lo->rootcg_cmd_list); lo->use_dio = lo->lo_flags & LO_FLAGS_DIRECT_IO; lo->lo_device = bdev; lo->lo_backing_file = file; @@ -1152,10 +1150,6 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) if (!release) blk_mq_freeze_queue(lo->lo_queue); - destroy_workqueue(lo->workqueue); - loop_free_idle_workers(lo, true); - del_timer_sync(&lo->timer); - spin_lock_irq(&lo->lo_lock); filp = lo->lo_backing_file; lo->lo_backing_file = NULL; @@ -1749,6 +1743,10 @@ static void lo_free_disk(struct gendisk *disk) { struct loop_device *lo = disk->private_data; + if (lo->workqueue) + destroy_workqueue(lo->workqueue); + loop_free_idle_workers(lo, true); + del_timer_sync(&lo->timer); mutex_destroy(&lo->lo_mutex); kfree(lo); } @@ -2012,6 +2010,8 @@ static int loop_add(int i) lo->lo_number = i; spin_lock_init(&lo->lo_lock); spin_lock_init(&lo->lo_work_lock); + INIT_WORK(&lo->rootcg_work, loop_rootcg_workfn); + INIT_LIST_HEAD(&lo->rootcg_cmd_list); disk->major = LOOP_MAJOR; disk->first_minor = i << part_shift; disk->minors = 1 << part_shift;