From patchwork Tue Mar 27 04:39:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10309185 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9CD1060325 for ; Tue, 27 Mar 2018 04:40:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 90E1429AAD for ; Tue, 27 Mar 2018 04:40:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8509329AB5; Tue, 27 Mar 2018 04:40: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=-6.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_HI autolearn=unavailable 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 2B8EF29AAF for ; Tue, 27 Mar 2018 04:40:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751253AbeC0EkY (ORCPT ); Tue, 27 Mar 2018 00:40:24 -0400 Received: from mail-pg0-f67.google.com ([74.125.83.67]:34111 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751231AbeC0EkW (ORCPT ); Tue, 27 Mar 2018 00:40:22 -0400 Received: by mail-pg0-f67.google.com with SMTP id q6so50430pgr.1 for ; Mon, 26 Mar 2018 21:40:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=twS1ohF1YSg2UZpsQuZjmWTrizH00ASZD0s/iF9rRcI=; b=NUQv7YDJj4r2vPBNNPinlq1ZbHyWNbMQcMkEtexnEbW7W0igP4vVFv8j1Bg3+5/m5T zT7o2aIR263NwbINM+BxwoKYcant1dnv38oh/LV8lraZfjCQXTH5KKWaEIiH+1iqpQZS KYR10LrQ/mY7hRARAO146bG609laNw+ko771mwdf2BN7uRO0ZF/vhWqCVE/XGztVQo5y c/vLfbWhoRV/eanQoktsH0A8pW19jt/VvF8EGbi+HLOhvTu6TSgHRKHb+/D+LQghxnf/ MJ5EENG9gFQ88JVy7gq5tC+rGwC/kwqJ7POGEl3b38UUwwUudoIz3THxe3JkdIcAWt+Z KwzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=twS1ohF1YSg2UZpsQuZjmWTrizH00ASZD0s/iF9rRcI=; b=XAbsPTvIAziCm8tf9yHdAczl022pxtrY47nfg6EOVo/iDiO2xTkThMJWt72NK2szSG WJxns+kjVSXnUMc90cle9vUvwpGVFRJYk2JhpSzLWFpcs8rCzENlRIir9rgeWChPq00r 4EDZeyYqUTF0HF3G4UjySdpXD339VyCOSmH9dJMFoUp+s7wnrq0tJNTZpLvM1d661tbz /SSRa0bQaB1r97BeiT9ddoCQK3WqXJCZbrvy09WKP/laq3t8HE0yRc72MpmOfR5QZ/Ic SQsuQp0s/drndvb46Jhq/1MswEzxx/lH1SVcMmKOh3rQznW7DpUyjpvlYH+1EC2bV+Qn +62w== X-Gm-Message-State: AElRT7ELItugzFgc7t22+x3uy/GBvORNpt82jNBjqrD5gaZttB3WMZ6/ Nym2Q7Wr++odcWsCXGSBthn3GA== X-Google-Smtp-Source: AG47ELvIEcl+ySu/gTGaGX1vALwei6nBTZC/l+zGr8sTc6i87GntBBbowacoZ2lWv44R/ItijlCYpA== X-Received: by 10.98.214.218 with SMTP id a87mr27276041pfl.124.1522125621991; Mon, 26 Mar 2018 21:40:21 -0700 (PDT) Received: from localhost.localdomain ([2601:602:8801:8110:e6a7:a0ff:fe0b:c9a8]) by smtp.gmail.com with ESMTPSA id e21sm587892pfi.68.2018.03.26.21.40.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Mar 2018 21:40:20 -0700 (PDT) From: Omar Sandoval To: linux-block@vger.kernel.org Cc: Jens Axboe , kernel-team@fb.com, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 1/2] loop: don't call into filesystem while holding lo_ctl_mutex Date: Mon, 26 Mar 2018 21:39:11 -0700 Message-Id: <1f5e0cb1ff94eec231ae638221b7885a6836d70b.1522125370.git.osandov@fb.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: References: In-Reply-To: References: Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval 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 --- drivers/block/loop.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index ed6fafdc5377..93a60bda7608 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1167,21 +1167,17 @@ 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 = 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; @@ -1194,7 +1190,19 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) 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 @@ -1374,7 +1382,8 @@ 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); - 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)) @@ -1383,7 +1392,8 @@ 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); - 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)) @@ -1544,7 +1554,7 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, 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: