Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp6265887imu; Mon, 21 Jan 2019 06:05:49 -0800 (PST) X-Google-Smtp-Source: ALg8bN7Jj+H0B8HuwJFUnA9ZTFWWikE9NbKhgD/pMBrvUw+N1mh0GLMKL2X50vS/IAcoPJa0exaB X-Received: by 2002:a65:5bc4:: with SMTP id o4mr28504768pgr.426.1548079549092; Mon, 21 Jan 2019 06:05:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548079549; cv=none; d=google.com; s=arc-20160816; b=RYIzJHMKACkD3KryjTZoMy5SVbtgvo/0llD8JsoX2NmWE+sZjhQalM80CDo4vnYhar px4I+cdcMa3dBPKJ7pwHjQsvA7Dv7j3OdjrNfZkP9nIp7SMcadT5Vn+s2sFdoaluxyVH HXpKWrIFJvF6+CdDMEVNvrG0hFtHAtXo3zitqRxjcg7CgHlmo4KME12fbI+qHqt+bVPP eDW1dPG32DVZcBhHEDiJbrARCwmQqaFaLGYRCDg8+OwaORIqxFKVhOZ6YxhVdGcCk3oF Fw+Etz9ivmw0dFaOdSPbs4VnfSqBFYUElFL2kFByJTuRsTdw0J5zI2tmIkzgeCKPVfGT SYnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=zCcG8RSaaIrOTma4ZUZsL2GHeyparnSgYZjOREMLtls=; b=aYR62tWcMX8RrfzgkrhY1P9j0KCLVoat7Nd+VVNXSTkySmPUc7DZWd91SEte8F5P8l A+NpUzm4LjBZ5PaIyo2cj9RfdCblxgNX1gbZKmpbMzN92TMDZw9zxny5xRq7H75MxOaE tX0jOIOtujJa8JY7NoWwMnxTOCxnBD2TCY1rKYKttsa/uoG62NYDM1/sn0hQ8SY8y8ER /yWOLsLruZ9xTbAjgBGDUhzVVXiXkv6vaIVFszYReIO9F7cDJs0DDaU4Inp7jvN6wUJH GNGxOPNPcH2DQ/iDCYtddHMHrCcLRMb+MRXfdn5km0eSV/mEAYVt1lb2DwbMlffYFm8i QGWA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=PDcLKoYE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t1si11681396pgj.542.2019.01.21.06.05.33; Mon, 21 Jan 2019 06:05:49 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=PDcLKoYE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731842AbfAUODb (ORCPT + 99 others); Mon, 21 Jan 2019 09:03:31 -0500 Received: from mail.kernel.org ([198.145.29.99]:50814 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729420AbfAUOC7 (ORCPT ); Mon, 21 Jan 2019 09:02:59 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id EA6282089F; Mon, 21 Jan 2019 14:02:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1548079378; bh=v1nieTBXuQ8t1CiAZHAun7B58d33N/oKTFfp7SDlIuY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PDcLKoYE2fdxGp32A1AhRGkYTZZL3Xt2kBbTUzCrwSrK4NUCQwINWQSYGSLorjL18 Xz4IOLT+li/BXfz6/pp/XKS165nZVkfTTIg8tvDkpJuaborg2qT6l2zRaXpb4s253k Np9tvwslh/7SrYHQ0GAJSbi4qrqOiAPZawLrUDCs= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jan Kara , Jens Axboe Subject: [PATCH 4.19 84/99] loop: Push lo_ctl_mutex down into individual ioctls Date: Mon, 21 Jan 2019 14:49:16 +0100 Message-Id: <20190121134917.299674203@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190121134913.924726465@linuxfoundation.org> References: <20190121134913.924726465@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jan Kara commit a13165441d58b216adbd50252a9cc829d78a6bce upstream. 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 Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/block/loop.c | 88 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 25 deletions(-) --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1394,70 +1394,108 @@ static int loop_set_block_size(struct lo 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; }