Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2372604imu; Thu, 24 Jan 2019 11:35:50 -0800 (PST) X-Google-Smtp-Source: ALg8bN7wP+/W0gG4Dd0yEBEHJAjvXB1A6Qp1KdnoS/UayZcqPA377k6KKaWTu3+ORJCgHSEhw3oY X-Received: by 2002:a63:fe0a:: with SMTP id p10mr7100942pgh.265.1548358550150; Thu, 24 Jan 2019 11:35:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548358550; cv=none; d=google.com; s=arc-20160816; b=CdIIR+hfL8au+zexzZQKEmK/Xj43PTtRCf9lUHBRQVQ5leILee4Ty0h+sRQorBSMs0 eghd6tmeLmej9WpO82ngtDtH1OEH4r1zn5GouDSioO0azr6Q0FCk0qvPcWvaDdqE6CdN 5sQns2RCi58or3RQ+6NO7AxTEtseusqpf61H4rFhcb0KapRq2qMFivQzQcpqKfVh9GBN vl+XGQY7dLnZRJfT9stfGN0WNHQbIzKuuvwBP8o9PZEKiA7yFm/OZyOsQ17YjmKvVV0w rqWqjh/AWOBdfLEfucoZme6fXOpHLevW8yahT2DfqreXj530speRUudUwI58C+V6Br65 KEZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=vholAXE8+W5tA65OYyweKjlUvDi0z0uGZFOGjy+gL5M=; b=wsDvuA+I6xuToPVJ2zeJhO4HclOuXB84BhICmcAkNutV5jr1VA5wKepiTXVPfvsVtk IQMuRt82AG397173Zb0y2VE4xRD9QDHZiXaYwW/2QF+GevQTPwvfjofv1i94PozOOdBZ KugRjvSJ69WRorO8MknqInZoWzUe57zb4aNeZyM9kC6VmqSlsBZfGuEsPmnNmHc/2utB fzPmFTgDTUsCjiyEtNrIvP+CUfIlyAxY4KIsuBJNKBDyuHpUTlIwAqGPpPiKl0ZyKOtd w6VAe9tzZQolUgFJOsc2TVCjZIvp902sub5OmlxHg7y+ooZ9gJaRLRZjNwrWHaFG+5Ft XmJw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=T8jLg08U; 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 j21si11675891pfn.277.2019.01.24.11.35.35; Thu, 24 Jan 2019 11:35:50 -0800 (PST) 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=T8jLg08U; 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 S1731990AbfAXTdX (ORCPT + 99 others); Thu, 24 Jan 2019 14:33:23 -0500 Received: from mail.kernel.org ([198.145.29.99]:33074 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731979AbfAXTdR (ORCPT ); Thu, 24 Jan 2019 14:33:17 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (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 3B6E8218D4; Thu, 24 Jan 2019 19:33:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1548358396; bh=aMb6kBX7NGR3zvOoH3QSyrWHV1kuvUMxREKAVrQ3J3k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=T8jLg08U7Zh/ioyAXhNkSuscRS0YnIZ/ae8O1VqooGD5iTupgYuAPp+tRXRLbf/dW RahhYKDmtO8ZRO1+A6bQXXqNB05GLz9pkRb3Zxq6dkBoSQd7LvG1sprggkyvOikZiV xnWXTIlUq6D4CCT9H9zOHdoG9Sg5DQPg7T1doxQg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Scott Mayhew , Anna Schumaker , Qian Lu Subject: [PATCH 4.14 58/63] nfs: fix a deadlock in nfs client initialization Date: Thu, 24 Jan 2019 20:20:47 +0100 Message-Id: <20190124190202.138301116@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190124190155.176570028@linuxfoundation.org> References: <20190124190155.176570028@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Scott Mayhew commit c156618e15101a9cc8c815108fec0300a0ec6637 upstream. The following deadlock can occur between a process waiting for a client to initialize in while walking the client list during nfsv4 server trunking detection and another process waiting for the nfs_clid_init_mutex so it can initialize that client: Process 1 Process 2 --------- --------- spin_lock(&nn->nfs_client_lock); list_add_tail(&CLIENTA->cl_share_link, &nn->nfs_client_list); spin_unlock(&nn->nfs_client_lock); spin_lock(&nn->nfs_client_lock); list_add_tail(&CLIENTB->cl_share_link, &nn->nfs_client_list); spin_unlock(&nn->nfs_client_lock); mutex_lock(&nfs_clid_init_mutex); nfs41_walk_client_list(clp, result, cred); nfs_wait_client_init_complete(CLIENTA); (waiting for nfs_clid_init_mutex) Make sure nfs_match_client() only evaluates clients that have completed initialization in order to prevent that deadlock. This patch also fixes v4.0 trunking behavior by not marking the client NFS_CS_READY until the clientid has been confirmed. Signed-off-by: Scott Mayhew Signed-off-by: Anna Schumaker Signed-off-by: Qian Lu Signed-off-by: Greg Kroah-Hartman --- fs/nfs/client.c | 11 +++++++++++ fs/nfs/nfs4client.c | 17 +++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -291,12 +291,23 @@ static struct nfs_client *nfs_match_clie const struct sockaddr *sap = data->addr; struct nfs_net *nn = net_generic(data->net, nfs_net_id); +again: list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) { const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; /* Don't match clients that failed to initialise properly */ if (clp->cl_cons_state < 0) continue; + /* If a client is still initializing then we need to wait */ + if (clp->cl_cons_state > NFS_CS_READY) { + atomic_inc(&clp->cl_count); + spin_unlock(&nn->nfs_client_lock); + nfs_wait_client_init_complete(clp); + nfs_put_client(clp); + spin_lock(&nn->nfs_client_lock); + goto again; + } + /* Different NFS versions cannot share the same nfs_client */ if (clp->rpc_ops != data->nfs_mod->rpc_ops) continue; --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -404,15 +404,19 @@ struct nfs_client *nfs4_init_client(stru if (error < 0) goto error; - if (!nfs4_has_session(clp)) - nfs_mark_client_ready(clp, NFS_CS_READY); - error = nfs4_discover_server_trunking(clp, &old); if (error < 0) goto error; - if (clp != old) + if (clp != old) { clp->cl_preserve_clid = true; + /* + * Mark the client as having failed initialization so other + * processes walking the nfs_client_list in nfs_match_client() + * won't try to use it. + */ + nfs_mark_client_ready(clp, -EPERM); + } nfs_put_client(clp); clear_bit(NFS_CS_TSM_POSSIBLE, &clp->cl_flags); return old; @@ -539,6 +543,9 @@ int nfs40_walk_client_list(struct nfs_cl spin_lock(&nn->nfs_client_lock); list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { + if (pos == new) + goto found; + status = nfs4_match_client(pos, new, &prev, nn); if (status < 0) goto out_unlock; @@ -559,6 +566,7 @@ int nfs40_walk_client_list(struct nfs_cl * way that a SETCLIENTID_CONFIRM to pos can succeed is * if new and pos point to the same server: */ +found: atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); @@ -572,6 +580,7 @@ int nfs40_walk_client_list(struct nfs_cl case 0: nfs4_swap_callback_idents(pos, new); pos->cl_confirm = new->cl_confirm; + nfs_mark_client_ready(pos, NFS_CS_READY); prev = NULL; *result = pos;