From patchwork Mon Mar 26 23:16:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10308967 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 0EE2160212 for ; Mon, 26 Mar 2018 23:16:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 082C729878 for ; Mon, 26 Mar 2018 23:16:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F10BD2987D; Mon, 26 Mar 2018 23:16:44 +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 9A65B29878 for ; Mon, 26 Mar 2018 23:16:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752500AbeCZXQg (ORCPT ); Mon, 26 Mar 2018 19:16:36 -0400 Received: from mail-pl0-f65.google.com ([209.85.160.65]:39740 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752487AbeCZXQf (ORCPT ); Mon, 26 Mar 2018 19:16:35 -0400 Received: by mail-pl0-f65.google.com with SMTP id s24-v6so2536239plq.6 for ; Mon, 26 Mar 2018 16:16:35 -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=Qd5FlMDo6bu8gi/1N2NMZ/6MVNZrL94Ni+jSpj4V6oyGGq600GZrPSD4wDzdvnLAh6 9eYPIkPbBbNdaiALnvcR3LoK1ajp2rlz+TSK1O09xkvmAIuz/z4P8mtZf+PVCvx3cy/E 2+I7pn+1CQzLbTvnybASiRmLbwKoDzfn7XUmhihF03u6N5qkdGCJahMvdjKJGfshahqE dwwatwFaOujO6AYFl9s0BrUWuT0VwbPOhumprAu2/rg5lYCQgH7SLQf10ojjYncw4ClU 6JNXSBD5p9L/cOoC8jDNNcWkwU0lIIH9XbqFShbhZV3DUNEYq0yMQ7EBBuI2CoPCtreD 5KDQ== 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=R+0MTEIguBwrarkkpBwQlWaLEtS1kz6O0aM6euILN1dyV8FafwPl9SA0NbGtVPz8Lf GN5RswoplUS2oQAmGfZN53iglCREL84PAwPjRdAbuNosOXk0LJ+5ZoUm2QZipOKqS1X3 XcALZEyiBQaeLSkmRGmmF2k86nBlFseqx0VSua5XY0p3OGaEYA5dqToRc2fstz+neNO1 7d1FzEkWcBda1aDSGNQRFcm5EciXiRvqeJ1IQNkp6LI17VZatm2KQbYxyguGyoKq9J6+ FMXZtDM430sPg8fSPKk2C9kWSdEEvmv8+3GXyfmP/bV2IcRF9W5AMguq0g2FhOnJyZsW cSig== X-Gm-Message-State: AElRT7FUkU7k+IQqdvoz52a1muUuvVb+tmr0JoeenKsE4ON+YtrBSXku tFD8yI0P8jz1SJBBn6Q5QfJRDw5iz6I= X-Google-Smtp-Source: AG47ELuDbeBF23G8y6JN/3XgDYJUaHTc/WhKzNUlpjhQ8fK6Il96Z9CpPQRlHG65tDtQUu8XhglmMg== X-Received: by 2002:a17:902:6001:: with SMTP id r1-v6mr42448382plj.330.1522106194512; Mon, 26 Mar 2018 16:16:34 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:200::5:324b]) by smtp.gmail.com with ESMTPSA id y18sm30701567pfe.67.2018.03.26.16.16.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Mar 2018 16:16:34 -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 1/2] loop: don't call into filesystem while holding lo_ctl_mutex Date: Mon, 26 Mar 2018 16:16:25 -0700 Message-Id: <1f5e0cb1ff94eec231ae638221b7885a6836d70b.1522106130.git.osandov@fb.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: References: In-Reply-To: References: 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: 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: