From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A8E414430D; Thu, 11 Apr 2024 10:02:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712829764; cv=none; b=u5o3JKp1LzPHxF6Jj5lfYtWg2y/LKmABNR3k0knHMQnNaMagaYEzba7v064KIdFWUl8iX/NobhplPmymMW04BtZ+xVoclWy5GnfB2ouwS61KcojlSZa/44PZX+vhkaOYPNw6tXK6DT8qSmXfxE5WCfQNEtGctvJ4FSe7EmwzgtA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712829764; c=relaxed/simple; bh=/t6ReAU+EosdAn8gkBcrZ3yvSHL9n6ngEkUQkut3U0o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EKNyMSzPcznpY2ccPJo7OPy73lVP7K/3Q/Qh8ZBZWPTEQQK2cJzJ2vCGZGWt3WcF6ToBM4pP9KF+OfN0Yyq4QdRvAMfsS8BLQUYMW+IGN9v0tWUIp2ZxqamL98dQFeO7DJ0/7S0/rcRWKBdwmqE6za0ol3omTvhBPZPop2Fg/qQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=FIURd8gr; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="FIURd8gr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E3150C433F1; Thu, 11 Apr 2024 10:02:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1712829764; bh=/t6ReAU+EosdAn8gkBcrZ3yvSHL9n6ngEkUQkut3U0o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FIURd8grifye4IvIsromcf6GQNajDzdGiPADgEd6oVLgYI4YCIxlsoOCnf5ZqIewM sWbBmh38msO0jNHaP4DUtfDGfTLUfTjw8qOj1EKwd2L1nQWxrp/fSQNv1syktqDGvf H4OB4TtC+LH/GZdGiXolPsHYexVmUw2JlgFrFGoM= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Martijn Coenen , Christoph Hellwig , Jens Axboe , Genjian Zhang Subject: [PATCH 4.19 098/175] loop: Factor out configuring loop from status Date: Thu, 11 Apr 2024 11:55:21 +0200 Message-ID: <20240411095422.519156657@linuxfoundation.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240411095419.532012976@linuxfoundation.org> References: <20240411095419.532012976@linuxfoundation.org> User-Agent: quilt/0.67 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Martijn Coenen [ Upstream commit 0c3796c244598122a5d59d56f30d19390096817f ] Factor out this code into a separate function, so it can be reused by other code more easily. Signed-off-by: Martijn Coenen Reviewed-by: Christoph Hellwig Signed-off-by: Jens Axboe Signed-off-by: Genjian Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/block/loop.c | 117 +++++++++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 50 deletions(-) --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1231,75 +1231,43 @@ static int loop_clr_fd(struct loop_devic return __loop_clr_fd(lo, false); } +/** + * loop_set_status_from_info - configure device from loop_info + * @lo: struct loop_device to configure + * @info: struct loop_info64 to configure the device with + * + * Configures the loop device parameters according to the passed + * in loop_info64 configuration. + */ static int -loop_set_status(struct loop_device *lo, const struct loop_info64 *info) +loop_set_status_from_info(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; - bool size_changed = false; - err = mutex_lock_killable(&loop_ctl_mutex); - if (err) - return err; - if (lo->lo_encrypt_key_size && - !uid_eq(lo->lo_key_owner, uid) && - !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; - } - - if (lo->lo_offset != info->lo_offset || - lo->lo_sizelimit != info->lo_sizelimit) { - size_changed = true; - sync_blockdev(lo->lo_device); - invalidate_bdev(lo->lo_device); - } - - /* 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) has still dirty pages (nrpages=%lu)\n", - __func__, lo->lo_number, lo->lo_file_name, - lo->lo_device->bd_inode->i_mapping->nrpages); - goto out_unfreeze; - } + if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) + return -EINVAL; err = loop_release_xfer(lo); if (err) - goto out_unfreeze; + return err; if (info->lo_encrypt_type) { unsigned int type = info->lo_encrypt_type; - if (type >= MAX_LO_CRYPT) { - err = -EINVAL; - goto out_unfreeze; - } + if (type >= MAX_LO_CRYPT) + return -EINVAL; xfer = xfer_funcs[type]; - if (xfer == NULL) { - err = -EINVAL; - goto out_unfreeze; - } + if (xfer == NULL) + return -EINVAL; } else xfer = NULL; err = loop_init_xfer(lo, xfer, info); if (err) - goto out_unfreeze; + return err; lo->lo_offset = info->lo_offset; lo->lo_sizelimit = info->lo_sizelimit; @@ -1326,6 +1294,55 @@ loop_set_status(struct loop_device *lo, lo->lo_key_owner = uid; } + return 0; +} + +static int +loop_set_status(struct loop_device *lo, const struct loop_info64 *info) +{ + int err; + struct block_device *bdev; + kuid_t uid = current_uid(); + bool partscan = false; + bool size_changed = false; + + err = mutex_lock_killable(&loop_ctl_mutex); + if (err) + return err; + if (lo->lo_encrypt_key_size && + !uid_eq(lo->lo_key_owner, uid) && + !capable(CAP_SYS_ADMIN)) { + err = -EPERM; + goto out_unlock; + } + if (lo->lo_state != Lo_bound) { + err = -ENXIO; + goto out_unlock; + } + + if (lo->lo_offset != info->lo_offset || + lo->lo_sizelimit != info->lo_sizelimit) { + size_changed = true; + sync_blockdev(lo->lo_device); + invalidate_bdev(lo->lo_device); + } + + /* 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) has still dirty pages (nrpages=%lu)\n", + __func__, lo->lo_number, lo->lo_file_name, + lo->lo_device->bd_inode->i_mapping->nrpages); + goto out_unfreeze; + } + + err = loop_set_status_from_info(lo, info); + if (err) + goto out_unfreeze; + if (size_changed) { loff_t new_size = get_size(lo->lo_offset, lo->lo_sizelimit, lo->lo_backing_file);