Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2652294pxj; Mon, 14 Jun 2021 04:05:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx0xneWaL0e5BCqcPV2iOOw2Bfq4g6sQ/4a7lzXhjRFM3HzqMwvBxqorzFHGgXpm3eG9fhw X-Received: by 2002:a17:906:5657:: with SMTP id v23mr2704822ejr.90.1623668750700; Mon, 14 Jun 2021 04:05:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623668750; cv=none; d=google.com; s=arc-20160816; b=XlhlihcldsbiBaryd+cxVIB94TIbmM3PTZVrGG73Ioz12QJMlMV1fMxDlIWgOKoHan XCFaV8nBxumsBqvFtYVhl8qg7wZJTneEaTXmYJhD9eqpNq5tfOsgMBys85Zlyy4Vp55e HTEb8xhXmpSSIZITDkQyvaFR+P+y/3I0vOA5jojj0UlIyKIp8K74ZTm0dUlk1IGau83Q MpIPXJA730QzS7DR8Hx8XsJb4oN+LjG3zqpOaZuPsfL8qjthJh+/vpRfn2NkZXLWX253 e5GWqhSheY4pJwcaMR9KbU4yzH9EzizifT+2OdtK0Jx8u6sxN4qbQQfcm+S43noYogm3 jNIg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=LjHsB6TiM7SZ1IkvR7mO4UwYo0MCve9XatYlbFmQGso=; b=OquYzk8objPvQ3yY6fnJdcPSwTPiwdzs9+DCjPlCWE5updBAPnxnHojC3jhWyZMjKo fV0XpU8qw2oLiW+IUiyHb/xhRCw7FtrmIS7xKF6mP89ihj9Jf2j39GDrE5sLCxKhxkMd 0R0mIP9KntPvB2hqYIBfMXaxTUw3GgpcABC6Wd8E1ycOMyDCQdUt8agHvGO70SUphyLz ktKAELl+YVqg+++Ce6iDv0l0U5sMqMXgnkig/XZ0qQ5TmEhIm6iuUBkBGVQWTm3SLEBb RfgogzbRd/8DyFp131+V8BDVp6N42EQ7Cl+EoR+Ga4id0UKebDtc7VNm2uwPxdKjUdLf vtmg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PbMvBqGd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id rv18si10970056ejb.596.2021.06.14.04.05.28; Mon, 14 Jun 2021 04:05:50 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PbMvBqGd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234222AbhFNLDd (ORCPT + 99 others); Mon, 14 Jun 2021 07:03:33 -0400 Received: from mail.kernel.org ([198.145.29.99]:60644 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234886AbhFNKyr (ORCPT ); Mon, 14 Jun 2021 06:54:47 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9DB2561494; Mon, 14 Jun 2021 10:40:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1623667220; bh=8DNWtnmNiX3F4P/ffvSRUlTlkgzE9yRqTEF0v5kCsoQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PbMvBqGdH6TQQCkdzYchYiGvNnDJyMj7n3ENn4pdQsU+QrfcwScXuQ/fVBu5bxRKc 5lk5/MYBXFJup9wHfR7AjqydqmkOI3kmrt5xn+w0AcAuK4ts3ZRqF8FfgXA1DeAXCJ aUt+BUkOlY4ALfcGVp2q5XrHX2BlfwzU3BubFh1k= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "zhangxiaoxu (A)" , Trond Myklebust , Sasha Levin Subject: [PATCH 5.4 73/84] NFSv4: Fix deadlock between nfs4_evict_inode() and nfs4_opendata_get_inode() Date: Mon, 14 Jun 2021 12:27:51 +0200 Message-Id: <20210614102648.841065470@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210614102646.341387537@linuxfoundation.org> References: <20210614102646.341387537@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Trond Myklebust [ Upstream commit dfe1fe75e00e4c724ede7b9e593f6f680e446c5f ] If the inode is being evicted, but has to return a delegation first, then it can cause a deadlock in the corner case where the server reboots before the delegreturn completes, but while the call to iget5_locked() in nfs4_opendata_get_inode() is waiting for the inode free to complete. Since the open call still holds a session slot, the reboot recovery cannot proceed. In order to break the logjam, we can turn the delegation return into a privileged operation for the case where we're evicting the inode. We know that in that case, there can be no other state recovery operation that conflicts. Reported-by: zhangxiaoxu (A) Fixes: 5fcdfacc01f3 ("NFSv4: Return delegations synchronously in evict_inode") Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin --- fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4proc.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index c4a98cbda6dd..5708b5a636f1 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -203,6 +203,7 @@ struct nfs4_exception { struct inode *inode; nfs4_stateid *stateid; long timeout; + unsigned char task_is_privileged : 1; unsigned char delay : 1, recovering : 1, retry : 1; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ff54ba3c8247..ff48d7b23f07 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -581,6 +581,8 @@ int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_ goto out_retry; } if (exception->recovering) { + if (exception->task_is_privileged) + return -EDEADLOCK; ret = nfs4_wait_clnt_recover(clp); if (test_bit(NFS_MIG_FAILED, &server->mig_status)) return -EIO; @@ -606,6 +608,8 @@ nfs4_async_handle_exception(struct rpc_task *task, struct nfs_server *server, goto out_retry; } if (exception->recovering) { + if (exception->task_is_privileged) + return -EDEADLOCK; rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); @@ -6231,6 +6235,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) struct nfs4_exception exception = { .inode = data->inode, .stateid = &data->stateid, + .task_is_privileged = data->args.seq_args.sa_privileged, }; if (!nfs4_sequence_done(task, &data->res.seq_res)) @@ -6349,7 +6354,6 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, data = kzalloc(sizeof(*data), GFP_NOFS); if (data == NULL) return -ENOMEM; - nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, 0); nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_CLEANUP, @@ -6377,6 +6381,12 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, } } + if (!data->inode) + nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, + 1); + else + nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, + 0); task_setup_data.callback_data = data; msg.rpc_argp = &data->args; msg.rpc_resp = &data->res; -- 2.30.2