From patchwork Wed Oct 10 10:04:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634299 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 686E369B6 for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 53200295BF for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 47F3E2960A; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DFDEA295BF for ; Wed, 10 Oct 2018 10:04:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726573AbeJJRZr (ORCPT ); Wed, 10 Oct 2018 13:25:47 -0400 Received: from mx2.suse.de ([195.135.220.15]:34832 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726741AbeJJRZr (ORCPT ); Wed, 10 Oct 2018 13:25:47 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 0F8F2B041; Wed, 10 Oct 2018 10:04:20 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 8BD8B1E0341; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Tetsuo Handa , Jan Kara Subject: [PATCH 01/15] block/loop: Don't grab "struct file" for vfs_getattr() operation. Date: Wed, 10 Oct 2018 12:04:01 +0200 Message-Id: <20181010100415.26525-2-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Tetsuo Handa vfs_getattr() needs "struct path" rather than "struct file". Let's use path_get()/path_put() rather than get_file()/fput(). Signed-off-by: Tetsuo Handa Reviewed-by: Jan Kara Signed-off-by: Jan Kara --- drivers/block/loop.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index ea9debf59b22..50c81ff44ae2 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1205,7 +1205,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) static int loop_get_status(struct loop_device *lo, struct loop_info64 *info) { - struct file *file; + struct path path; struct kstat stat; int ret; @@ -1230,16 +1230,16 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) } /* Drop lo_ctl_mutex while we call into the filesystem. */ - file = get_file(lo->lo_backing_file); + path = lo->lo_backing_file->f_path; + path_get(&path); mutex_unlock(&lo->lo_ctl_mutex); - ret = vfs_getattr(&file->f_path, &stat, STATX_INO, - AT_STATX_SYNC_AS_STAT); + ret = vfs_getattr(&path, &stat, STATX_INO, AT_STATX_SYNC_AS_STAT); if (!ret) { info->lo_device = huge_encode_dev(stat.dev); info->lo_inode = stat.ino; info->lo_rdevice = huge_encode_dev(stat.rdev); } - fput(file); + path_put(&path); return ret; } From patchwork Wed Oct 10 10:04:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634285 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DF16969B5 for ; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AD94C296A0 for ; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A0D5729BE5; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DDBEA295E9 for ; Wed, 10 Oct 2018 10:04:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727006AbeJJRZs (ORCPT ); Wed, 10 Oct 2018 13:25:48 -0400 Received: from mx2.suse.de ([195.135.220.15]:34840 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726896AbeJJRZs (ORCPT ); Wed, 10 Oct 2018 13:25:48 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 2C31CB044; Wed, 10 Oct 2018 10:04:20 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 8DB8E1E3618; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Tetsuo Handa , Jan Kara Subject: [PATCH 02/15] block/loop: Use global lock for ioctl() operation. Date: Wed, 10 Oct 2018 12:04:02 +0200 Message-Id: <20181010100415.26525-3-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Tetsuo Handa syzbot is reporting NULL pointer dereference [1] which is caused by race condition between ioctl(loop_fd, LOOP_CLR_FD, 0) versus ioctl(other_loop_fd, LOOP_SET_FD, loop_fd) due to traversing other loop devices at loop_validate_file() without holding corresponding lo->lo_ctl_mutex locks. Since ioctl() request on loop devices is not frequent operation, we don't need fine grained locking. Let's use global lock in order to allow safe traversal at loop_validate_file(). Note that syzbot is also reporting circular locking dependency between bdev->bd_mutex and lo->lo_ctl_mutex [2] which is caused by calling blkdev_reread_part() with lock held. This patch does not address it. [1] https://syzkaller.appspot.com/bug?id=f3cfe26e785d85f9ee259f385515291d21bd80a3 [2] https://syzkaller.appspot.com/bug?id=bf154052f0eea4bc7712499e4569505907d15889 Signed-off-by: Tetsuo Handa Reported-by: syzbot Reviewed-by: Jan Kara Signed-off-by: Jan Kara --- drivers/block/loop.c | 58 ++++++++++++++++++++++++++-------------------------- drivers/block/loop.h | 1 - 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 50c81ff44ae2..d0f1b7106572 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -84,6 +84,7 @@ static DEFINE_IDR(loop_index_idr); static DEFINE_MUTEX(loop_index_mutex); +static DEFINE_MUTEX(loop_ctl_mutex); static int max_part; static int part_shift; @@ -1047,7 +1048,7 @@ static int loop_clr_fd(struct loop_device *lo) */ if (atomic_read(&lo->lo_refcnt) > 1) { lo->lo_flags |= LO_FLAGS_AUTOCLEAR; - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); return 0; } @@ -1100,12 +1101,12 @@ static int loop_clr_fd(struct loop_device *lo) if (!part_shift) lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; loop_unprepare_queue(lo); - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); /* - * Need not hold lo_ctl_mutex to fput backing file. - * Calling fput holding lo_ctl_mutex triggers a circular + * Need not hold loop_ctl_mutex to fput backing file. + * Calling fput holding loop_ctl_mutex triggers a circular * lock dependency possibility warning as fput can take - * bd_mutex which is usually taken before lo_ctl_mutex. + * bd_mutex which is usually taken before loop_ctl_mutex. */ fput(filp); return 0; @@ -1210,7 +1211,7 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) int ret; if (lo->lo_state != Lo_bound) { - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); return -ENXIO; } @@ -1229,10 +1230,10 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) lo->lo_encrypt_key_size); } - /* Drop lo_ctl_mutex while we call into the filesystem. */ + /* Drop loop_ctl_mutex while we call into the filesystem. */ path = lo->lo_backing_file->f_path; path_get(&path); - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); ret = vfs_getattr(&path, &stat, STATX_INO, AT_STATX_SYNC_AS_STAT); if (!ret) { info->lo_device = huge_encode_dev(stat.dev); @@ -1324,7 +1325,7 @@ loop_get_status_old(struct loop_device *lo, struct loop_info __user *arg) { int err; if (!arg) { - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); return -EINVAL; } err = loop_get_status(lo, &info64); @@ -1342,7 +1343,7 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) { int err; if (!arg) { - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); return -EINVAL; } err = loop_get_status(lo, &info64); @@ -1400,7 +1401,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, struct loop_device *lo = bdev->bd_disk->private_data; int err; - err = mutex_lock_killable_nested(&lo->lo_ctl_mutex, 1); + err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); if (err) goto out_unlocked; @@ -1412,7 +1413,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, err = loop_change_fd(lo, bdev, arg); break; case LOOP_CLR_FD: - /* loop_clr_fd would have unlocked lo_ctl_mutex on success */ + /* loop_clr_fd would have unlocked loop_ctl_mutex on success */ err = loop_clr_fd(lo); if (!err) goto out_unlocked; @@ -1425,7 +1426,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, break; case LOOP_GET_STATUS: err = loop_get_status_old(lo, (struct loop_info __user *) arg); - /* loop_get_status() unlocks lo_ctl_mutex */ + /* loop_get_status() unlocks loop_ctl_mutex */ goto out_unlocked; case LOOP_SET_STATUS64: err = -EPERM; @@ -1435,7 +1436,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, break; case LOOP_GET_STATUS64: err = loop_get_status64(lo, (struct loop_info64 __user *) arg); - /* loop_get_status() unlocks lo_ctl_mutex */ + /* loop_get_status() unlocks loop_ctl_mutex */ goto out_unlocked; case LOOP_SET_CAPACITY: err = -EPERM; @@ -1455,7 +1456,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, default: err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; } - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); out_unlocked: return err; @@ -1572,7 +1573,7 @@ loop_get_status_compat(struct loop_device *lo, int err; if (!arg) { - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); return -EINVAL; } err = loop_get_status(lo, &info64); @@ -1589,19 +1590,19 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, switch(cmd) { case LOOP_SET_STATUS: - err = mutex_lock_killable(&lo->lo_ctl_mutex); + err = mutex_lock_killable(&loop_ctl_mutex); if (!err) { err = loop_set_status_compat(lo, (const struct compat_loop_info __user *)arg); - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); } break; case LOOP_GET_STATUS: - err = mutex_lock_killable(&lo->lo_ctl_mutex); + err = mutex_lock_killable(&loop_ctl_mutex); if (!err) { err = loop_get_status_compat(lo, (struct compat_loop_info __user *)arg); - /* loop_get_status() unlocks lo_ctl_mutex */ + /* loop_get_status() unlocks loop_ctl_mutex */ } break; case LOOP_SET_CAPACITY: @@ -1648,7 +1649,7 @@ static void __lo_release(struct loop_device *lo) if (atomic_dec_return(&lo->lo_refcnt)) return; - mutex_lock(&lo->lo_ctl_mutex); + mutex_lock(&loop_ctl_mutex); if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) { /* * In autoclear mode, stop the loop thread @@ -1666,7 +1667,7 @@ static void __lo_release(struct loop_device *lo) blk_mq_unfreeze_queue(lo->lo_queue); } - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); } static void lo_release(struct gendisk *disk, fmode_t mode) @@ -1712,10 +1713,10 @@ static int unregister_transfer_cb(int id, void *ptr, void *data) struct loop_device *lo = ptr; struct loop_func_table *xfer = data; - mutex_lock(&lo->lo_ctl_mutex); + mutex_lock(&loop_ctl_mutex); if (lo->lo_encryption == xfer) loop_release_xfer(lo); - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); return 0; } @@ -1896,7 +1897,6 @@ static int loop_add(struct loop_device **l, int i) if (!part_shift) disk->flags |= GENHD_FL_NO_PART_SCAN; disk->flags |= GENHD_FL_EXT_DEVT; - mutex_init(&lo->lo_ctl_mutex); atomic_set(&lo->lo_refcnt, 0); lo->lo_number = i; spin_lock_init(&lo->lo_lock); @@ -2009,21 +2009,21 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd, ret = loop_lookup(&lo, parm); if (ret < 0) break; - ret = mutex_lock_killable(&lo->lo_ctl_mutex); + ret = mutex_lock_killable(&loop_ctl_mutex); if (ret) break; if (lo->lo_state != Lo_unbound) { ret = -EBUSY; - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); break; } if (atomic_read(&lo->lo_refcnt) > 0) { ret = -EBUSY; - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); break; } lo->lo_disk->private_data = NULL; - mutex_unlock(&lo->lo_ctl_mutex); + mutex_unlock(&loop_ctl_mutex); idr_remove(&loop_index_idr, lo->lo_number); loop_remove(lo); break; diff --git a/drivers/block/loop.h b/drivers/block/loop.h index 4d42c7af7de7..af75a5ee4094 100644 --- a/drivers/block/loop.h +++ b/drivers/block/loop.h @@ -54,7 +54,6 @@ struct loop_device { spinlock_t lo_lock; int lo_state; - struct mutex lo_ctl_mutex; struct kthread_worker worker; struct task_struct *worker_task; bool use_dio; From patchwork Wed Oct 10 10:04:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634283 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CD96B14DB for ; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1003E295DE for ; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0446129622; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1569F295DE for ; Wed, 10 Oct 2018 10:04:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726741AbeJJRZr (ORCPT ); Wed, 10 Oct 2018 13:25:47 -0400 Received: from mx2.suse.de ([195.135.220.15]:34836 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726861AbeJJRZr (ORCPT ); Wed, 10 Oct 2018 13:25:47 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 0AEB4AEFD; Wed, 10 Oct 2018 10:04:20 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 92C661E361A; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 03/15] loop: Fold __loop_release into loop_release Date: Wed, 10 Oct 2018 12:04:03 +0200 Message-Id: <20181010100415.26525-4-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP __loop_release() has a single call site. Fold it there. This is currently not a huge win but it will make following replacement of loop_index_mutex more obvious. Signed-off-by: Jan Kara --- drivers/block/loop.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index d0f1b7106572..cc43d835fe6f 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1642,12 +1642,15 @@ static int lo_open(struct block_device *bdev, fmode_t mode) return err; } -static void __lo_release(struct loop_device *lo) +static void lo_release(struct gendisk *disk, fmode_t mode) { + struct loop_device *lo; int err; + mutex_lock(&loop_index_mutex); + lo = disk->private_data; if (atomic_dec_return(&lo->lo_refcnt)) - return; + goto unlock_index; mutex_lock(&loop_ctl_mutex); if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) { @@ -1657,7 +1660,7 @@ static void __lo_release(struct loop_device *lo) */ err = loop_clr_fd(lo); if (!err) - return; + goto unlock_index; } else if (lo->lo_state == Lo_bound) { /* * Otherwise keep thread (if running) and config, @@ -1668,12 +1671,7 @@ static void __lo_release(struct loop_device *lo) } mutex_unlock(&loop_ctl_mutex); -} - -static void lo_release(struct gendisk *disk, fmode_t mode) -{ - mutex_lock(&loop_index_mutex); - __lo_release(disk->private_data); +unlock_index: mutex_unlock(&loop_index_mutex); } From patchwork Wed Oct 10 10:04:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634289 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CFBEC5CAF for ; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6A6752960A for ; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5DB8F2964C; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4158D29627 for ; Wed, 10 Oct 2018 10:04:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726969AbeJJRZs (ORCPT ); Wed, 10 Oct 2018 13:25:48 -0400 Received: from mx2.suse.de ([195.135.220.15]:34838 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726867AbeJJRZr (ORCPT ); Wed, 10 Oct 2018 13:25:47 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 11975B043; Wed, 10 Oct 2018 10:04:20 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 94DC81E361B; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 04/15] loop: Get rid of loop_index_mutex Date: Wed, 10 Oct 2018 12:04:04 +0200 Message-Id: <20181010100415.26525-5-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Now that loop_ctl_mutex is global, just get rid of loop_index_mutex as there is no good reason to keep these two separate and it just complicates the locking. Signed-off-by: Jan Kara --- drivers/block/loop.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index cc43d835fe6f..3fa5e63944a4 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -83,7 +83,6 @@ #include static DEFINE_IDR(loop_index_idr); -static DEFINE_MUTEX(loop_index_mutex); static DEFINE_MUTEX(loop_ctl_mutex); static int max_part; @@ -1627,9 +1626,11 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, static int lo_open(struct block_device *bdev, fmode_t mode) { struct loop_device *lo; - int err = 0; + int err; - mutex_lock(&loop_index_mutex); + err = mutex_lock_killable(&loop_ctl_mutex); + if (err) + return err; lo = bdev->bd_disk->private_data; if (!lo) { err = -ENXIO; @@ -1638,7 +1639,7 @@ static int lo_open(struct block_device *bdev, fmode_t mode) atomic_inc(&lo->lo_refcnt); out: - mutex_unlock(&loop_index_mutex); + mutex_unlock(&loop_ctl_mutex); return err; } @@ -1647,12 +1648,11 @@ static void lo_release(struct gendisk *disk, fmode_t mode) struct loop_device *lo; int err; - mutex_lock(&loop_index_mutex); + mutex_lock(&loop_ctl_mutex); lo = disk->private_data; if (atomic_dec_return(&lo->lo_refcnt)) - goto unlock_index; + goto out_unlock; - mutex_lock(&loop_ctl_mutex); if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) { /* * In autoclear mode, stop the loop thread @@ -1660,7 +1660,7 @@ static void lo_release(struct gendisk *disk, fmode_t mode) */ err = loop_clr_fd(lo); if (!err) - goto unlock_index; + return; } else if (lo->lo_state == Lo_bound) { /* * Otherwise keep thread (if running) and config, @@ -1670,9 +1670,8 @@ static void lo_release(struct gendisk *disk, fmode_t mode) blk_mq_unfreeze_queue(lo->lo_queue); } +out_unlock: mutex_unlock(&loop_ctl_mutex); -unlock_index: - mutex_unlock(&loop_index_mutex); } static const struct block_device_operations lo_fops = { @@ -1973,7 +1972,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data) struct kobject *kobj; int err; - mutex_lock(&loop_index_mutex); + mutex_lock(&loop_ctl_mutex); err = loop_lookup(&lo, MINOR(dev) >> part_shift); if (err < 0) err = loop_add(&lo, MINOR(dev) >> part_shift); @@ -1981,7 +1980,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data) kobj = NULL; else kobj = get_disk_and_module(lo->lo_disk); - mutex_unlock(&loop_index_mutex); + mutex_unlock(&loop_ctl_mutex); *part = 0; return kobj; @@ -1991,9 +1990,13 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd, unsigned long parm) { struct loop_device *lo; - int ret = -ENOSYS; + int ret; - mutex_lock(&loop_index_mutex); + ret = mutex_lock_killable(&loop_ctl_mutex); + if (ret) + return ret; + + ret = -ENOSYS; switch (cmd) { case LOOP_CTL_ADD: ret = loop_lookup(&lo, parm); @@ -2007,9 +2010,6 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd, ret = loop_lookup(&lo, parm); if (ret < 0) break; - ret = mutex_lock_killable(&loop_ctl_mutex); - if (ret) - break; if (lo->lo_state != Lo_unbound) { ret = -EBUSY; mutex_unlock(&loop_ctl_mutex); @@ -2021,7 +2021,6 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd, break; } lo->lo_disk->private_data = NULL; - mutex_unlock(&loop_ctl_mutex); idr_remove(&loop_index_idr, lo->lo_number); loop_remove(lo); break; @@ -2031,7 +2030,7 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd, break; ret = loop_add(&lo, -1); } - mutex_unlock(&loop_index_mutex); + mutex_unlock(&loop_ctl_mutex); return ret; } @@ -2115,10 +2114,10 @@ static int __init loop_init(void) THIS_MODULE, loop_probe, NULL, NULL); /* pre-create number of devices given by config or max_loop */ - mutex_lock(&loop_index_mutex); + mutex_lock(&loop_ctl_mutex); for (i = 0; i < nr; i++) loop_add(&lo, i); - mutex_unlock(&loop_index_mutex); + mutex_unlock(&loop_ctl_mutex); printk(KERN_INFO "loop: module loaded\n"); return 0; From patchwork Wed Oct 10 10:04:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634309 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 347AF69B4 for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E89E295E9 for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 12875295DE; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9C8D329627 for ; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727031AbeJJRZt (ORCPT ); Wed, 10 Oct 2018 13:25:49 -0400 Received: from mx2.suse.de ([195.135.220.15]:34910 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726935AbeJJRZs (ORCPT ); Wed, 10 Oct 2018 13:25:48 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id D13E6B04C; Wed, 10 Oct 2018 10:04:20 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 994821E361C; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 05/15] loop: Push lo_ctl_mutex down into individual ioctls Date: Wed, 10 Oct 2018 12:04:05 +0200 Message-Id: <20181010100415.26525-6-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Push acquisition of lo_ctl_mutex down into individual ioctl handling branches. This is a preparatory step for pushing the lock down into individual ioctl handling functions so that they can release the lock as they need it. We also factor out some simple ioctl handlers that will not need any special handling to reduce unnecessary code duplication. Signed-off-by: Jan Kara --- drivers/block/loop.c | 88 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 3fa5e63944a4..b7b3b4ae0896 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1394,70 +1394,108 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg) return 0; } -static int lo_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long arg) +static int lo_simple_ioctl(struct loop_device *lo, unsigned int cmd, + unsigned long arg) { - struct loop_device *lo = bdev->bd_disk->private_data; int err; err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); if (err) - goto out_unlocked; + return err; + switch (cmd) { + case LOOP_SET_CAPACITY: + err = loop_set_capacity(lo); + break; + case LOOP_SET_DIRECT_IO: + err = loop_set_dio(lo, arg); + break; + case LOOP_SET_BLOCK_SIZE: + err = loop_set_block_size(lo, arg); + break; + default: + err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; + } + mutex_unlock(&loop_ctl_mutex); + return err; +} + +static int lo_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) +{ + struct loop_device *lo = bdev->bd_disk->private_data; + int err; switch (cmd) { case LOOP_SET_FD: + err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (err) + return err; err = loop_set_fd(lo, mode, bdev, arg); + mutex_unlock(&loop_ctl_mutex); break; case LOOP_CHANGE_FD: + err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (err) + return err; err = loop_change_fd(lo, bdev, arg); + mutex_unlock(&loop_ctl_mutex); break; case LOOP_CLR_FD: + err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (err) + return err; /* loop_clr_fd would have unlocked loop_ctl_mutex on success */ err = loop_clr_fd(lo); - if (!err) - goto out_unlocked; + if (err) + mutex_unlock(&loop_ctl_mutex); break; case LOOP_SET_STATUS: err = -EPERM; - if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) + if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) { + err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (err) + return err; err = loop_set_status_old(lo, (struct loop_info __user *)arg); + mutex_unlock(&loop_ctl_mutex); + } break; case LOOP_GET_STATUS: + err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (err) + return err; err = loop_get_status_old(lo, (struct loop_info __user *) arg); /* loop_get_status() unlocks loop_ctl_mutex */ - goto out_unlocked; + break; case LOOP_SET_STATUS64: err = -EPERM; - if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) + if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) { + err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (err) + return err; err = loop_set_status64(lo, (struct loop_info64 __user *) arg); + mutex_unlock(&loop_ctl_mutex); + } break; case LOOP_GET_STATUS64: + err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (err) + return err; err = loop_get_status64(lo, (struct loop_info64 __user *) arg); /* loop_get_status() unlocks loop_ctl_mutex */ - goto out_unlocked; - case LOOP_SET_CAPACITY: - err = -EPERM; - if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) - err = loop_set_capacity(lo); break; + case LOOP_SET_CAPACITY: case LOOP_SET_DIRECT_IO: - err = -EPERM; - if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) - err = loop_set_dio(lo, arg); - break; case LOOP_SET_BLOCK_SIZE: - err = -EPERM; - if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) - err = loop_set_block_size(lo, arg); - break; + if (!(mode & FMODE_WRITE) && !capable(CAP_SYS_ADMIN)) + return -EPERM; + /* Fall through */ default: - err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; + err = lo_simple_ioctl(lo, cmd, arg); + break; } - mutex_unlock(&loop_ctl_mutex); -out_unlocked: return err; } From patchwork Wed Oct 10 10:04:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634295 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D767B69BF for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7AB5B29615 for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F6262960A; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 05B0229635 for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726967AbeJJRZu (ORCPT ); Wed, 10 Oct 2018 13:25:50 -0400 Received: from mx2.suse.de ([195.135.220.15]:34946 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726867AbeJJRZt (ORCPT ); Wed, 10 Oct 2018 13:25:49 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id BD0A8B055; Wed, 10 Oct 2018 10:04:21 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 9D13E1E37AD; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 06/15] loop: Split setting of lo_state from loop_clr_fd Date: Wed, 10 Oct 2018 12:04:06 +0200 Message-Id: <20181010100415.26525-7-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Move setting of lo_state to Lo_rundown out into the callers. That will allow us to unlock loop_ctl_mutex while the loop device is protected from other changes by its special state. Signed-off-by: Jan Kara --- drivers/block/loop.c | 52 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index b7b3b4ae0896..2410921bd9ff 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -976,7 +976,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, loop_reread_partitions(lo, bdev); /* Grab the block_device to prevent its destruction after we - * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev). + * put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev). */ bdgrab(bdev); return 0; @@ -1026,31 +1026,15 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, return err; } -static int loop_clr_fd(struct loop_device *lo) +static int __loop_clr_fd(struct loop_device *lo) { struct file *filp = lo->lo_backing_file; gfp_t gfp = lo->old_gfp_mask; struct block_device *bdev = lo->lo_device; - if (lo->lo_state != Lo_bound) + if (WARN_ON_ONCE(lo->lo_state != Lo_rundown)) return -ENXIO; - /* - * If we've explicitly asked to tear down the loop device, - * and it has an elevated reference count, set it for auto-teardown when - * the last reference goes away. This stops $!~#$@ udev from - * preventing teardown because it decided that it needs to run blkid on - * the loopback device whenever they appear. xfstests is notorious for - * failing tests because blkid via udev races with a losetup - * /do something like mkfs/losetup -d causing the losetup -d - * command to fail with EBUSY. - */ - if (atomic_read(&lo->lo_refcnt) > 1) { - lo->lo_flags |= LO_FLAGS_AUTOCLEAR; - mutex_unlock(&loop_ctl_mutex); - return 0; - } - if (filp == NULL) return -EINVAL; @@ -1058,7 +1042,6 @@ static int loop_clr_fd(struct loop_device *lo) blk_mq_freeze_queue(lo->lo_queue); spin_lock_irq(&lo->lo_lock); - lo->lo_state = Lo_rundown; lo->lo_backing_file = NULL; spin_unlock_irq(&lo->lo_lock); @@ -1111,6 +1094,30 @@ static int loop_clr_fd(struct loop_device *lo) return 0; } +static int loop_clr_fd(struct loop_device *lo) +{ + if (lo->lo_state != Lo_bound) + return -ENXIO; + /* + * If we've explicitly asked to tear down the loop device, + * and it has an elevated reference count, set it for auto-teardown when + * the last reference goes away. This stops $!~#$@ udev from + * preventing teardown because it decided that it needs to run blkid on + * the loopback device whenever they appear. xfstests is notorious for + * failing tests because blkid via udev races with a losetup + * /do something like mkfs/losetup -d causing the losetup -d + * command to fail with EBUSY. + */ + if (atomic_read(&lo->lo_refcnt) > 1) { + lo->lo_flags |= LO_FLAGS_AUTOCLEAR; + mutex_unlock(&loop_ctl_mutex); + return 0; + } + lo->lo_state = Lo_rundown; + + return __loop_clr_fd(lo); +} + static int loop_set_status(struct loop_device *lo, const struct loop_info64 *info) { @@ -1692,11 +1699,14 @@ static void lo_release(struct gendisk *disk, fmode_t mode) goto out_unlock; if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) { + if (lo->lo_state != Lo_bound) + goto out_unlock; + lo->lo_state = Lo_rundown; /* * In autoclear mode, stop the loop thread * and remove configuration after last close. */ - err = loop_clr_fd(lo); + err = __loop_clr_fd(lo); if (!err) return; } else if (lo->lo_state == Lo_bound) { From patchwork Wed Oct 10 10:04:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634293 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 250FC69C1 for ; Wed, 10 Oct 2018 10:04:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 104A12960A for ; Wed, 10 Oct 2018 10:04:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 04FC129627; Wed, 10 Oct 2018 10:04:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 952022960A for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726861AbeJJRZv (ORCPT ); Wed, 10 Oct 2018 13:25:51 -0400 Received: from mx2.suse.de ([195.135.220.15]:34954 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727007AbeJJRZv (ORCPT ); Wed, 10 Oct 2018 13:25:51 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id C5C39B057; Wed, 10 Oct 2018 10:04:21 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id A06EA1E3AA4; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 07/15] loop: Push loop_ctl_mutex down into loop_clr_fd() Date: Wed, 10 Oct 2018 12:04:07 +0200 Message-Id: <20181010100415.26525-8-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP loop_clr_fd() has a weird locking convention that is expects loop_ctl_mutex held, releases it on success and keeps it on failure. Untangle the mess by moving locking of loop_ctl_mutex into loop_clr_fd(). Signed-off-by: Jan Kara --- drivers/block/loop.c | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 2410921bd9ff..be41d5dcecd2 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1028,15 +1028,22 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, static int __loop_clr_fd(struct loop_device *lo) { - struct file *filp = lo->lo_backing_file; + struct file *filp = NULL; gfp_t gfp = lo->old_gfp_mask; struct block_device *bdev = lo->lo_device; + int err = 0; - if (WARN_ON_ONCE(lo->lo_state != Lo_rundown)) - return -ENXIO; + mutex_lock(&loop_ctl_mutex); + if (WARN_ON_ONCE(lo->lo_state != Lo_rundown)) { + err = -ENXIO; + goto out_unlock; + } - if (filp == NULL) - return -EINVAL; + filp = lo->lo_backing_file; + if (filp == NULL) { + err = -EINVAL; + goto out_unlock; + } /* freeze request queue during the transition */ blk_mq_freeze_queue(lo->lo_queue); @@ -1083,6 +1090,7 @@ static int __loop_clr_fd(struct loop_device *lo) if (!part_shift) lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; loop_unprepare_queue(lo); +out_unlock: mutex_unlock(&loop_ctl_mutex); /* * Need not hold loop_ctl_mutex to fput backing file. @@ -1090,14 +1098,22 @@ static int __loop_clr_fd(struct loop_device *lo) * lock dependency possibility warning as fput can take * bd_mutex which is usually taken before loop_ctl_mutex. */ - fput(filp); - return 0; + if (filp) + fput(filp); + return err; } static int loop_clr_fd(struct loop_device *lo) { - if (lo->lo_state != Lo_bound) + int err; + + err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (err) + return err; + if (lo->lo_state != Lo_bound) { + mutex_unlock(&loop_ctl_mutex); return -ENXIO; + } /* * If we've explicitly asked to tear down the loop device, * and it has an elevated reference count, set it for auto-teardown when @@ -1114,6 +1130,7 @@ static int loop_clr_fd(struct loop_device *lo) return 0; } lo->lo_state = Lo_rundown; + mutex_unlock(&loop_ctl_mutex); return __loop_clr_fd(lo); } @@ -1448,14 +1465,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, mutex_unlock(&loop_ctl_mutex); break; case LOOP_CLR_FD: - err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); - if (err) - return err; - /* loop_clr_fd would have unlocked loop_ctl_mutex on success */ - err = loop_clr_fd(lo); - if (err) - mutex_unlock(&loop_ctl_mutex); - break; + return loop_clr_fd(lo); case LOOP_SET_STATUS: err = -EPERM; if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) { @@ -1691,7 +1701,6 @@ static int lo_open(struct block_device *bdev, fmode_t mode) static void lo_release(struct gendisk *disk, fmode_t mode) { struct loop_device *lo; - int err; mutex_lock(&loop_ctl_mutex); lo = disk->private_data; @@ -1702,13 +1711,13 @@ static void lo_release(struct gendisk *disk, fmode_t mode) if (lo->lo_state != Lo_bound) goto out_unlock; lo->lo_state = Lo_rundown; + mutex_unlock(&loop_ctl_mutex); /* * In autoclear mode, stop the loop thread * and remove configuration after last close. */ - err = __loop_clr_fd(lo); - if (!err) - return; + __loop_clr_fd(lo); + return; } else if (lo->lo_state == Lo_bound) { /* * Otherwise keep thread (if running) and config, From patchwork Wed Oct 10 10:04:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634301 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BA01F69B7 for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A3D5A2920D for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9842B295E9; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3A6E9295DE for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726925AbeJJRZt (ORCPT ); Wed, 10 Oct 2018 13:25:49 -0400 Received: from mx2.suse.de ([195.135.220.15]:34906 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726918AbeJJRZt (ORCPT ); Wed, 10 Oct 2018 13:25:49 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id B548AB045; Wed, 10 Oct 2018 10:04:20 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id A385D1E3AA5; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 08/15] loop: Push loop_ctl_mutex down to loop_get_status() Date: Wed, 10 Oct 2018 12:04:08 +0200 Message-Id: <20181010100415.26525-9-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Push loop_ctl_mutex down to loop_get_status() to avoid the unusual convention that the function gets called with loop_ctl_mutex held and releases it. Signed-off-by: Jan Kara --- drivers/block/loop.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index be41d5dcecd2..cb4eeff91238 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1233,6 +1233,9 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) struct kstat stat; int ret; + ret = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (ret) + return ret; if (lo->lo_state != Lo_bound) { mutex_unlock(&loop_ctl_mutex); return -ENXIO; @@ -1347,10 +1350,8 @@ loop_get_status_old(struct loop_device *lo, struct loop_info __user *arg) { struct loop_info64 info64; int err; - if (!arg) { - mutex_unlock(&loop_ctl_mutex); + if (!arg) return -EINVAL; - } err = loop_get_status(lo, &info64); if (!err) err = loop_info64_to_old(&info64, &info); @@ -1365,10 +1366,8 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) { struct loop_info64 info64; int err; - if (!arg) { - mutex_unlock(&loop_ctl_mutex); + if (!arg) return -EINVAL; - } err = loop_get_status(lo, &info64); if (!err && copy_to_user(arg, &info64, sizeof(info64))) err = -EFAULT; @@ -1478,12 +1477,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, } break; case LOOP_GET_STATUS: - err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); - if (err) - return err; - err = loop_get_status_old(lo, (struct loop_info __user *) arg); - /* loop_get_status() unlocks loop_ctl_mutex */ - break; + return loop_get_status_old(lo, (struct loop_info __user *) arg); case LOOP_SET_STATUS64: err = -EPERM; if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) { @@ -1496,12 +1490,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, } break; case LOOP_GET_STATUS64: - err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); - if (err) - return err; - err = loop_get_status64(lo, (struct loop_info64 __user *) arg); - /* loop_get_status() unlocks loop_ctl_mutex */ - break; + return loop_get_status64(lo, (struct loop_info64 __user *) arg); case LOOP_SET_CAPACITY: case LOOP_SET_DIRECT_IO: case LOOP_SET_BLOCK_SIZE: @@ -1626,10 +1615,8 @@ loop_get_status_compat(struct loop_device *lo, struct loop_info64 info64; int err; - if (!arg) { - mutex_unlock(&loop_ctl_mutex); + if (!arg) return -EINVAL; - } err = loop_get_status(lo, &info64); if (!err) err = loop_info64_to_compat(&info64, arg); @@ -1652,12 +1639,8 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, } break; case LOOP_GET_STATUS: - err = mutex_lock_killable(&loop_ctl_mutex); - if (!err) { - err = loop_get_status_compat(lo, - (struct compat_loop_info __user *)arg); - /* loop_get_status() unlocks loop_ctl_mutex */ - } + err = loop_get_status_compat(lo, + (struct compat_loop_info __user *)arg); break; case LOOP_SET_CAPACITY: case LOOP_CLR_FD: From patchwork Wed Oct 10 10:04:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634313 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 90B4569C2 for ; Wed, 10 Oct 2018 10:04:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 724AE2920D for ; Wed, 10 Oct 2018 10:04:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6678B295DE; Wed, 10 Oct 2018 10:04:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8B3EB295BF for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726935AbeJJRZt (ORCPT ); Wed, 10 Oct 2018 13:25:49 -0400 Received: from mx2.suse.de ([195.135.220.15]:34912 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726925AbeJJRZs (ORCPT ); Wed, 10 Oct 2018 13:25:48 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id D0F5BB04A; Wed, 10 Oct 2018 10:04:20 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id A7A3B1E3BE0; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 09/15] loop: Push loop_ctl_mutex down to loop_set_status() Date: Wed, 10 Oct 2018 12:04:09 +0200 Message-Id: <20181010100415.26525-10-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Push loop_ctl_mutex down to loop_set_status(). We will need this to be able to call loop_reread_partitions() without loop_ctl_mutex. Signed-off-by: Jan Kara --- drivers/block/loop.c | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index cb4eeff91238..5661489d11a7 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1142,46 +1142,55 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) struct loop_func_table *xfer; kuid_t uid = current_uid(); + err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (err) + return err; if (lo->lo_encrypt_key_size && !uid_eq(lo->lo_key_owner, uid) && - !capable(CAP_SYS_ADMIN)) - return -EPERM; - if (lo->lo_state != Lo_bound) - return -ENXIO; - if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) - return -EINVAL; + !capable(CAP_SYS_ADMIN)) { + err = -EPERM; + goto out_unlock; + } + if (lo->lo_state != Lo_bound) { + err = -ENXIO; + goto out_unlock; + } + if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) { + err = -EINVAL; + goto out_unlock; + } /* I/O need to be drained during transfer transition */ blk_mq_freeze_queue(lo->lo_queue); err = loop_release_xfer(lo); if (err) - goto exit; + goto out_unfreeze; if (info->lo_encrypt_type) { unsigned int type = info->lo_encrypt_type; if (type >= MAX_LO_CRYPT) { err = -EINVAL; - goto exit; + goto out_unfreeze; } xfer = xfer_funcs[type]; if (xfer == NULL) { err = -EINVAL; - goto exit; + goto out_unfreeze; } } else xfer = NULL; err = loop_init_xfer(lo, xfer, info); if (err) - goto exit; + goto out_unfreeze; if (lo->lo_offset != info->lo_offset || lo->lo_sizelimit != info->lo_sizelimit) { if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) { err = -EFBIG; - goto exit; + goto out_unfreeze; } } @@ -1213,7 +1222,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) /* update dio if lo_offset or transfer is changed */ __loop_update_dio(lo, lo->use_dio); - exit: +out_unfreeze: blk_mq_unfreeze_queue(lo->lo_queue); if (!err && (info->lo_flags & LO_FLAGS_PARTSCAN) && @@ -1222,6 +1231,8 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN; loop_reread_partitions(lo, lo->lo_device); } +out_unlock: + mutex_unlock(&loop_ctl_mutex); return err; } @@ -1468,12 +1479,8 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, case LOOP_SET_STATUS: err = -EPERM; if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) { - err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); - if (err) - return err; err = loop_set_status_old(lo, (struct loop_info __user *)arg); - mutex_unlock(&loop_ctl_mutex); } break; case LOOP_GET_STATUS: @@ -1481,12 +1488,8 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, case LOOP_SET_STATUS64: err = -EPERM; if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) { - err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); - if (err) - return err; err = loop_set_status64(lo, (struct loop_info64 __user *) arg); - mutex_unlock(&loop_ctl_mutex); } break; case LOOP_GET_STATUS64: @@ -1631,12 +1634,8 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, switch(cmd) { case LOOP_SET_STATUS: - err = mutex_lock_killable(&loop_ctl_mutex); - if (!err) { - err = loop_set_status_compat(lo, - (const struct compat_loop_info __user *)arg); - mutex_unlock(&loop_ctl_mutex); - } + err = loop_set_status_compat(lo, + (const struct compat_loop_info __user *)arg); break; case LOOP_GET_STATUS: err = loop_get_status_compat(lo, From patchwork Wed Oct 10 10:04:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634287 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E17FE17E1 for ; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5CC7295E9 for ; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BA1CF29C64; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5DB0629622 for ; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726936AbeJJRZt (ORCPT ); Wed, 10 Oct 2018 13:25:49 -0400 Received: from mx2.suse.de ([195.135.220.15]:34918 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726967AbeJJRZs (ORCPT ); Wed, 10 Oct 2018 13:25:48 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id ED089B04E; Wed, 10 Oct 2018 10:04:20 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id AC2261E3BE6; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 10/15] loop: Push loop_ctl_mutex down to loop_set_fd() Date: Wed, 10 Oct 2018 12:04:10 +0200 Message-Id: <20181010100415.26525-11-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Push lo_ctl_mutex down to loop_set_fd(). We will need this to be able to call loop_reread_partitions() without lo_ctl_mutex. Signed-off-by: Jan Kara --- drivers/block/loop.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 5661489d11a7..b4500d82238d 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -919,13 +919,17 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, if (!file) goto out; + error = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (error) + goto out_putf; + error = -EBUSY; if (lo->lo_state != Lo_unbound) - goto out_putf; + goto out_unlock; error = loop_validate_file(file, bdev); if (error) - goto out_putf; + goto out_unlock; mapping = file->f_mapping; inode = mapping->host; @@ -937,10 +941,10 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, error = -EFBIG; size = get_loop_size(lo, file); if ((loff_t)(sector_t)size != size) - goto out_putf; + goto out_unlock; error = loop_prepare_queue(lo); if (error) - goto out_putf; + goto out_unlock; error = 0; @@ -979,11 +983,14 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, * put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev). */ bdgrab(bdev); + mutex_unlock(&loop_ctl_mutex); return 0; - out_putf: +out_unlock: + mutex_unlock(&loop_ctl_mutex); +out_putf: fput(file); - out: +out: /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); return error; @@ -1461,12 +1468,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, switch (cmd) { case LOOP_SET_FD: - err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); - if (err) - return err; - err = loop_set_fd(lo, mode, bdev, arg); - mutex_unlock(&loop_ctl_mutex); - break; + return loop_set_fd(lo, mode, bdev, arg); case LOOP_CHANGE_FD: err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); if (err) From patchwork Wed Oct 10 10:04:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634311 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D764E69BE for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 91835295DE for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 85C5629627; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 388DF295DE for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726867AbeJJRZv (ORCPT ); Wed, 10 Oct 2018 13:25:51 -0400 Received: from mx2.suse.de ([195.135.220.15]:34952 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727016AbeJJRZu (ORCPT ); Wed, 10 Oct 2018 13:25:50 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id C4BE1B056; Wed, 10 Oct 2018 10:04:21 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id AFFDB1E3BFA; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 11/15] loop: Push loop_ctl_mutex down to loop_change_fd() Date: Wed, 10 Oct 2018 12:04:11 +0200 Message-Id: <20181010100415.26525-12-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Push loop_ctl_mutex down to loop_change_fd(). We will need this to be able to call loop_reread_partitions() without loop_ctl_mutex. Signed-off-by: Jan Kara --- drivers/block/loop.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index b4500d82238d..c53ad5e88a7d 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -692,19 +692,22 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, struct file *file, *old_file; int error; + error = mutex_lock_killable_nested(&loop_ctl_mutex, 1); + if (error) + return error; error = -ENXIO; if (lo->lo_state != Lo_bound) - goto out; + goto out_unlock; /* the loop device has to be read-only */ error = -EINVAL; if (!(lo->lo_flags & LO_FLAGS_READ_ONLY)) - goto out; + goto out_unlock; error = -EBADF; file = fget(arg); if (!file) - goto out; + goto out_unlock; error = loop_validate_file(file, bdev); if (error) @@ -731,11 +734,13 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, fput(old_file); if (lo->lo_flags & LO_FLAGS_PARTSCAN) loop_reread_partitions(lo, bdev); + mutex_unlock(&loop_ctl_mutex); return 0; - out_putf: +out_putf: fput(file); - out: +out_unlock: + mutex_unlock(&loop_ctl_mutex); return error; } @@ -1470,12 +1475,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, case LOOP_SET_FD: return loop_set_fd(lo, mode, bdev, arg); case LOOP_CHANGE_FD: - err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); - if (err) - return err; - err = loop_change_fd(lo, bdev, arg); - mutex_unlock(&loop_ctl_mutex); - break; + return loop_change_fd(lo, bdev, arg); case LOOP_CLR_FD: return loop_clr_fd(lo); case LOOP_SET_STATUS: From patchwork Wed Oct 10 10:04:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634297 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9077A69B9 for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7B51C2920D for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6FEDA295E9; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 16DC22920D for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726918AbeJJRZt (ORCPT ); Wed, 10 Oct 2018 13:25:49 -0400 Received: from mx2.suse.de ([195.135.220.15]:34948 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726970AbeJJRZt (ORCPT ); Wed, 10 Oct 2018 13:25:49 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id BC32CB052; Wed, 10 Oct 2018 10:04:21 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id B33441E3C0A; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 12/15] loop: Move special partition reread handling in loop_clr_fd() Date: Wed, 10 Oct 2018 12:04:12 +0200 Message-Id: <20181010100415.26525-13-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The call of __blkdev_reread_part() from loop_reread_partition() happens only when we need to invalidate partitions from loop_release(). Thus move a detection for this into loop_clr_fd() and simplify loop_reread_partition(). This makes loop_reread_partition() safe to use without loop_ctl_mutex because we use only lo->lo_number and lo->lo_file_name in case of error for reporting purposes (thus possibly reporting outdate information is not a big deal) and we are safe from 'lo' going away under us by elevated lo->lo_refcnt. Signed-off-by: Jan Kara --- drivers/block/loop.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index c53ad5e88a7d..db73fb5f16c7 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -631,18 +631,7 @@ static void loop_reread_partitions(struct loop_device *lo, { int rc; - /* - * bd_mutex has been held already in release path, so don't - * acquire it if this function is called in such case. - * - * If the reread partition isn't from release path, lo_refcnt - * must be at least one and it can only become zero when the - * current holder is released. - */ - if (!atomic_read(&lo->lo_refcnt)) - rc = __blkdev_reread_part(bdev); - else - rc = blkdev_reread_part(bdev); + rc = blkdev_reread_part(bdev); if (rc) pr_warn("%s: partition scan of loop%d (%s) failed (rc=%d)\n", __func__, lo->lo_number, lo->lo_file_name, rc); @@ -1096,8 +1085,24 @@ static int __loop_clr_fd(struct loop_device *lo) module_put(THIS_MODULE); blk_mq_unfreeze_queue(lo->lo_queue); - if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev) - loop_reread_partitions(lo, bdev); + if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev) { + /* + * bd_mutex has been held already in release path, so don't + * acquire it if this function is called in such case. + * + * If the reread partition isn't from release path, lo_refcnt + * must be at least one and it can only become zero when the + * current holder is released. + */ + if (!atomic_read(&lo->lo_refcnt)) + err = __blkdev_reread_part(bdev); + else + err = blkdev_reread_part(bdev); + pr_warn("%s: partition scan of loop%d failed (rc=%d)\n", + __func__, lo->lo_number, err); + /* Device is gone, no point in returning error */ + err = 0; + } lo->lo_flags = 0; if (!part_shift) lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; From patchwork Wed Oct 10 10:04:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634307 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 539F369C0 for ; Wed, 10 Oct 2018 10:04:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3DD33295DE for ; Wed, 10 Oct 2018 10:04:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 31FF429615; Wed, 10 Oct 2018 10:04:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C44ED295E9 for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727016AbeJJRZv (ORCPT ); Wed, 10 Oct 2018 13:25:51 -0400 Received: from mx2.suse.de ([195.135.220.15]:34908 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726861AbeJJRZt (ORCPT ); Wed, 10 Oct 2018 13:25:49 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id D2140B04D; Wed, 10 Oct 2018 10:04:20 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id B74941E3C27; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 13/15] loop: Move loop_reread_partitions() out of loop_ctl_mutex Date: Wed, 10 Oct 2018 12:04:13 +0200 Message-Id: <20181010100415.26525-14-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Calling loop_reread_partitions() under loop_ctl_mutex causes lockdep to complain about circular lock dependency between bdev->bd_mutex and lo->lo_ctl_mutex. The problem is that on loop device open or close lo_open() and lo_release() get called with bdev->bd_mutex held and they need to acquire loop_ctl_mutex. OTOH when loop_reread_partitions() is called with loop_ctl_mutex held, it will call blkdev_reread_part() which acquires bdev->bd_mutex. See syzbot report for details [1]. Move all calls of loop_rescan_partitions() out of loop_ctl_mutex to avoid lockdep warning and fix deadlock possibility. [1] https://syzkaller.appspot.com/bug?id=bf154052f0eea4bc7712499e4569505907d1588 Reported-by: syzbot Signed-off-by: Jan Kara --- drivers/block/loop.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index db73fb5f16c7..0d54c3ee3a96 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -680,6 +680,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, { struct file *file, *old_file; int error; + bool partscan; error = mutex_lock_killable_nested(&loop_ctl_mutex, 1); if (error) @@ -721,9 +722,10 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, blk_mq_unfreeze_queue(lo->lo_queue); fput(old_file); - if (lo->lo_flags & LO_FLAGS_PARTSCAN) - loop_reread_partitions(lo, bdev); + partscan = lo->lo_flags & LO_FLAGS_PARTSCAN; mutex_unlock(&loop_ctl_mutex); + if (partscan) + loop_reread_partitions(lo, bdev); return 0; out_putf: @@ -904,6 +906,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, int lo_flags = 0; int error; loff_t size; + bool partscan; /* This is safe, since we have a reference from open(). */ __module_get(THIS_MODULE); @@ -970,14 +973,15 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, lo->lo_state = Lo_bound; if (part_shift) lo->lo_flags |= LO_FLAGS_PARTSCAN; - if (lo->lo_flags & LO_FLAGS_PARTSCAN) - loop_reread_partitions(lo, bdev); + partscan = lo->lo_flags & LO_FLAGS_PARTSCAN; /* Grab the block_device to prevent its destruction after we * put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev). */ bdgrab(bdev); mutex_unlock(&loop_ctl_mutex); + if (partscan) + loop_reread_partitions(lo, bdev); return 0; out_unlock: @@ -1158,6 +1162,8 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) int err; struct loop_func_table *xfer; kuid_t uid = current_uid(); + struct block_device *bdev; + bool partscan = false; err = mutex_lock_killable_nested(&loop_ctl_mutex, 1); if (err) @@ -1246,10 +1252,13 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) !(lo->lo_flags & LO_FLAGS_PARTSCAN)) { lo->lo_flags |= LO_FLAGS_PARTSCAN; lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN; - loop_reread_partitions(lo, lo->lo_device); + bdev = lo->lo_device; + partscan = true; } out_unlock: mutex_unlock(&loop_ctl_mutex); + if (partscan) + loop_reread_partitions(lo, bdev); return err; } From patchwork Wed Oct 10 10:04:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634305 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4285F69BA for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 28B4E295E9 for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1CDE5295DE; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AD2E82960A for ; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726970AbeJJRZu (ORCPT ); Wed, 10 Oct 2018 13:25:50 -0400 Received: from mx2.suse.de ([195.135.220.15]:34916 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726967AbeJJRZu (ORCPT ); Wed, 10 Oct 2018 13:25:50 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 23FB1B058; Wed, 10 Oct 2018 10:04:22 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id BB5341E3C2F; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 14/15] loop: Fix deadlock when calling blkdev_reread_part() Date: Wed, 10 Oct 2018 12:04:14 +0200 Message-Id: <20181010100415.26525-15-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Calling blkdev_reread_part() under loop_ctl_mutex causes lockdep to complain about circular lock dependency between bdev->bd_mutex and lo->lo_ctl_mutex. The problem is that on loop device open or close lo_open() and lo_release() get called with bdev->bd_mutex held and they need to acquire loop_ctl_mutex. OTOH when loop_reread_partitions() is called with loop_ctl_mutex held, it will call blkdev_reread_part() which acquires bdev->bd_mutex. See syzbot report for details [1]. Move call to blkdev_reread_part() in __loop_clr_fd() from under loop_ctl_mutex to finish fixing of the lockdep warning and the possible deadlock. [1] https://syzkaller.appspot.com/bug?id=bf154052f0eea4bc7712499e4569505907d1588 Reported-by: syzbot Signed-off-by: Jan Kara --- drivers/block/loop.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 0d54c3ee3a96..d6b3fac25040 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1031,12 +1031,14 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, return err; } -static int __loop_clr_fd(struct loop_device *lo) +static int __loop_clr_fd(struct loop_device *lo, bool release) { struct file *filp = NULL; gfp_t gfp = lo->old_gfp_mask; struct block_device *bdev = lo->lo_device; int err = 0; + bool partscan = false; + int lo_number; mutex_lock(&loop_ctl_mutex); if (WARN_ON_ONCE(lo->lo_state != Lo_rundown)) { @@ -1089,7 +1091,15 @@ static int __loop_clr_fd(struct loop_device *lo) module_put(THIS_MODULE); blk_mq_unfreeze_queue(lo->lo_queue); - if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev) { + partscan = lo->lo_flags & LO_FLAGS_PARTSCAN && bdev; + lo_number = lo->lo_number; + lo->lo_flags = 0; + if (!part_shift) + lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; + loop_unprepare_queue(lo); +out_unlock: + mutex_unlock(&loop_ctl_mutex); + if (partscan) { /* * bd_mutex has been held already in release path, so don't * acquire it if this function is called in such case. @@ -1098,21 +1108,15 @@ static int __loop_clr_fd(struct loop_device *lo) * must be at least one and it can only become zero when the * current holder is released. */ - if (!atomic_read(&lo->lo_refcnt)) + if (release) err = __blkdev_reread_part(bdev); else err = blkdev_reread_part(bdev); pr_warn("%s: partition scan of loop%d failed (rc=%d)\n", - __func__, lo->lo_number, err); + __func__, lo_number, err); /* Device is gone, no point in returning error */ err = 0; } - lo->lo_flags = 0; - if (!part_shift) - lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; - loop_unprepare_queue(lo); -out_unlock: - mutex_unlock(&loop_ctl_mutex); /* * Need not hold loop_ctl_mutex to fput backing file. * Calling fput holding loop_ctl_mutex triggers a circular @@ -1153,7 +1157,7 @@ static int loop_clr_fd(struct loop_device *lo) lo->lo_state = Lo_rundown; mutex_unlock(&loop_ctl_mutex); - return __loop_clr_fd(lo); + return __loop_clr_fd(lo, false); } static int @@ -1714,7 +1718,7 @@ static void lo_release(struct gendisk *disk, fmode_t mode) * In autoclear mode, stop the loop thread * and remove configuration after last close. */ - __loop_clr_fd(lo); + __loop_clr_fd(lo, true); return; } else if (lo->lo_state == Lo_bound) { /* From patchwork Wed Oct 10 10:04:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 10634303 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1DCF769BB for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 053F8295DE for ; Wed, 10 Oct 2018 10:04:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EE2A5295E9; Wed, 10 Oct 2018 10:04:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1616129635 for ; Wed, 10 Oct 2018 10:04:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726896AbeJJRZs (ORCPT ); Wed, 10 Oct 2018 13:25:48 -0400 Received: from mx2.suse.de ([195.135.220.15]:34916 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726936AbeJJRZs (ORCPT ); Wed, 10 Oct 2018 13:25:48 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 13FF6B051; Wed, 10 Oct 2018 10:04:21 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id C00711E3C43; Wed, 10 Oct 2018 12:04:18 +0200 (CEST) From: Jan Kara To: Jens Axboe Cc: , Tetsuo Handa , Jan Kara Subject: [PATCH 15/15] loop: Avoid circular locking dependency between loop_ctl_mutex and bd_mutex Date: Wed, 10 Oct 2018 12:04:15 +0200 Message-Id: <20181010100415.26525-16-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181010100415.26525-1-jack@suse.cz> References: <20181010100415.26525-1-jack@suse.cz> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Code in loop_change_fd() drops reference to the old file (and also the new file in a failure case) under loop_ctl_mutex. Similarly to a situation in loop_set_fd() this can create a circular locking dependency if this was the last reference holding the file open. Delay dropping of the file reference until we have released loop_ctl_mutex. Reported-by: Tetsuo Handa Signed-off-by: Jan Kara --- drivers/block/loop.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index d6b3fac25040..a517247a32fa 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -678,7 +678,7 @@ static int loop_validate_file(struct file *file, struct block_device *bdev) static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, unsigned int arg) { - struct file *file, *old_file; + struct file *file = NULL, *old_file; int error; bool partscan; @@ -687,21 +687,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, return error; error = -ENXIO; if (lo->lo_state != Lo_bound) - goto out_unlock; + goto out_err; /* the loop device has to be read-only */ error = -EINVAL; if (!(lo->lo_flags & LO_FLAGS_READ_ONLY)) - goto out_unlock; + goto out_err; error = -EBADF; file = fget(arg); if (!file) - goto out_unlock; + goto out_err; error = loop_validate_file(file, bdev); if (error) - goto out_putf; + goto out_err; old_file = lo->lo_backing_file; @@ -709,7 +709,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, /* size of the new backing store needs to be the same */ if (get_loop_size(lo, file) != get_loop_size(lo, old_file)) - goto out_putf; + goto out_err; /* and ... switch */ blk_mq_freeze_queue(lo->lo_queue); @@ -720,18 +720,22 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); loop_update_dio(lo); blk_mq_unfreeze_queue(lo->lo_queue); - - fput(old_file); partscan = lo->lo_flags & LO_FLAGS_PARTSCAN; mutex_unlock(&loop_ctl_mutex); + /* + * We must drop file reference outside of loop_ctl_mutex as dropping + * the file ref can take bd_mutex which creates circular locking + * dependency. + */ + fput(old_file); if (partscan) loop_reread_partitions(lo, bdev); return 0; -out_putf: - fput(file); -out_unlock: +out_err: mutex_unlock(&loop_ctl_mutex); + if (file) + fput(file); return error; }