Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp1945571imm; Thu, 24 May 2018 03:23:19 -0700 (PDT) X-Google-Smtp-Source: AB8JxZo9VdDSjyolYW8mUykEIcSyowm87ewraZu3BjKx3Sn2SdnL8VgYbEZX3mIjNn6kYzpTyNnc X-Received: by 2002:a62:d605:: with SMTP id r5-v6mr6717560pfg.8.1527157399749; Thu, 24 May 2018 03:23:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527157399; cv=none; d=google.com; s=arc-20160816; b=LQLDAW50gBrX4PbMjlszXWz2KNnT55znS84ILwvy7LcNU9R8kXbc8O165wS2hycOB2 I6is52GJIZE3EoAzVUArFGwl7ZO/8pICqX1Zecuvdaor6fTuba1oGmVbHwkzisTtPYRv 11n1CZkqSG+7K6INoMIHn53/ZnDBAKDQiN2LjC0h41fV7H6jiAFnCsjROu4ywXjr7giQ mZe0zxUptiSUcIzmJTJYj8oRZb5q9MM08aR8khZO3cvoaPhHcZ5ULEnWxixejVtvwCOt /BnXYGPjwZaf3Si2UB0AHB6DJibu2QUnVJokZx8VUtxzl2I6uTUF8EbFtddmFLdn/mzN zAIg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=wr6oDSkdNCsUmM4/Mqs8/Pbg71No6yAhLSs9ZbX1pl0=; b=ZC3UDpu3B8+BEU+xJMuciMop9tIorqeBXS4LXxqVctw63rTag9uxGMEx4xdRiNbkDt phInk0gOz1Iij2axU0esS86tqbBjqmrxGifJbT/PSZIhljdkqId9CC2m1Bi4IJ9fg41y ntm/nYq+MXzagkJAh3A7c/MeIV4hJCfwPg/3Grdm9biv04H+En2ITlQMR5+SWtjm5jL6 m4LUB8Th5AYnMbPr7BpwydmXEMr3/8/95FJ3fFeCcPOkITUKB5euxLkX74dHbZDqTQZN eTN9K3JOMzQKjJC/1/dWQATy+GAiiV/xJaFNK4sgrStdyU0gKQrFq3zq1DtLMtj01S1/ dvWg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=LuOOpETs; 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 m14-v6si16749663pgs.178.2018.05.24.03.23.05; Thu, 24 May 2018 03:23:19 -0700 (PDT) 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=LuOOpETs; 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 S1031172AbeEXKCw (ORCPT + 99 others); Thu, 24 May 2018 06:02:52 -0400 Received: from mail.kernel.org ([198.145.29.99]:50452 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1031139AbeEXKCl (ORCPT ); Thu, 24 May 2018 06:02:41 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) (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 56ED820870; Thu, 24 May 2018 10:02:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1527156160; bh=xQSF4ckSySr9frUJa1VRXGV+Dwfms67outZg+noC/RQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LuOOpETsM4eHb9gCXRCheM38xDpls5UT123MgGwTKomS+Z/1E834q8LEUGSxt9Ld8 C32HLxi81Ld4Z5VrDmQrKoJOhTAR1pDjDXEvBZO65ARDzj+iCA69LDUel9lrPYtbiJ IrOQIP6HXc38DHCY0iJsOWhpsVGqx5WsT+iCaVdE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Omar Sandoval , Jens Axboe Subject: [PATCH 4.16 085/161] loop: dont call into filesystem while holding lo_ctl_mutex Date: Thu, 24 May 2018 11:38:30 +0200 Message-Id: <20180524093028.668538813@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180524093018.331893860@linuxfoundation.org> References: <20180524093018.331893860@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.16-stable review patch. If anyone has any objections, please let me know. ------------------ From: Omar Sandoval commit 2d1d4c1e591fd40bd7dafd868a249d7d00e215d5 upstream. We hit an issue where a loop device on NFS was stuck in loop_get_status() doing vfs_getattr() after the NFS server died, which caused a pile-up of uninterruptible processes waiting on lo_ctl_mutex. There's no reason to hold this lock while we wait on the filesystem; let's drop it so that other processes can do their thing. We need to grab a reference on lo_backing_file while we use it, and we can get rid of the check on lo_device, which has been unnecessary since commit a34c0ae9ebd6 ("[PATCH] loop: remove the bio remapping capability") in the linux-history tree. Signed-off-by: Omar Sandoval Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/block/loop.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1171,21 +1171,17 @@ loop_set_status(struct loop_device *lo, static int loop_get_status(struct loop_device *lo, struct loop_info64 *info) { - struct file *file = lo->lo_backing_file; + struct file *file; struct kstat stat; - int error; + int ret; - if (lo->lo_state != Lo_bound) + if (lo->lo_state != Lo_bound) { + mutex_unlock(&lo->lo_ctl_mutex); return -ENXIO; - error = vfs_getattr(&file->f_path, &stat, - STATX_INO, AT_STATX_SYNC_AS_STAT); - if (error) - return error; + } + memset(info, 0, sizeof(*info)); info->lo_number = lo->lo_number; - info->lo_device = huge_encode_dev(stat.dev); - info->lo_inode = stat.ino; - info->lo_rdevice = huge_encode_dev(lo->lo_device ? stat.rdev : stat.dev); info->lo_offset = lo->lo_offset; info->lo_sizelimit = lo->lo_sizelimit; info->lo_flags = lo->lo_flags; @@ -1198,7 +1194,19 @@ loop_get_status(struct loop_device *lo, memcpy(info->lo_encrypt_key, lo->lo_encrypt_key, lo->lo_encrypt_key_size); } - return 0; + + /* Drop lo_ctl_mutex while we call into the filesystem. */ + file = get_file(lo->lo_backing_file); + mutex_unlock(&lo->lo_ctl_mutex); + ret = vfs_getattr(&file->f_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); + return ret; } static void @@ -1378,7 +1386,8 @@ static int lo_ioctl(struct block_device break; case LOOP_GET_STATUS: err = loop_get_status_old(lo, (struct loop_info __user *) arg); - break; + /* loop_get_status() unlocks lo_ctl_mutex */ + goto out_unlocked; case LOOP_SET_STATUS64: err = -EPERM; if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) @@ -1387,7 +1396,8 @@ static int lo_ioctl(struct block_device break; case LOOP_GET_STATUS64: err = loop_get_status64(lo, (struct loop_info64 __user *) arg); - break; + /* loop_get_status() unlocks lo_ctl_mutex */ + goto out_unlocked; case LOOP_SET_CAPACITY: err = -EPERM; if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) @@ -1548,7 +1558,7 @@ static int lo_compat_ioctl(struct block_ mutex_lock(&lo->lo_ctl_mutex); err = loop_get_status_compat( lo, (struct compat_loop_info __user *) arg); - mutex_unlock(&lo->lo_ctl_mutex); + /* loop_get_status() unlocks lo_ctl_mutex */ break; case LOOP_SET_CAPACITY: case LOOP_CLR_FD: