From nobody Mon Sep 28 07:17:05 2026 Received: from mx0a-00154904.pphosted.com (mx0a-00154904.pphosted.com [148.163.133.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 568183CF21E; Tue, 25 Aug 2026 06:52:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.133.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787640724; cv=none; b=qPZYEcG8Mpoq2sGdeztf5sVe+1OQ953DWR/Bk1id6rPr7pXzA0M3hed05iFymjQHEcjVuGfTnDhscIRpFBDPC4CeaFHN0DDx5vEQfKIDyd1jVfjOM5CqpurB+cWOxe79auqFqq2Rnqz0lZO2dARPKul3fP26hlujh612+1mCUfg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787640724; c=relaxed/simple; bh=vVsFnEeAF7RgSF4eIN8pX+/YULBjqBQ2ILL0ti+V0fk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WGpRyqZBCVPydgJU4qQvvlOwgL+QNiA4973IqChVAA4mP6+SDHdDgIaxxAQD8mgOOGIUmqpI1xS0e3IhmBz77wDaJRs8CguR4CtlV26bH1csU4GAhExrPJB6ej3Wue7qGh0MVRjPKrObCKfDZ8TgqgmqO+pnEGiXOWbfJbPNFmg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=dell.com; spf=pass smtp.mailfrom=dell.com; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b=yet7n7wg; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b=G1eG1j4w; arc=none smtp.client-ip=148.163.133.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=dell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=dell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b="yet7n7wg"; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b="G1eG1j4w" Received: from pps.filterd (m0170390.ppops.net [127.0.0.1]) by mx0a-00154904.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67P2R0Fi3564430; Tue, 25 Aug 2026 02:51:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dell.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=smtpout1; bh=I2eM7lZ898NI tMJ2Atd2Uis5jVFbDnvth5GUgV9CY/o=; b=yet7n7wgCXvu4/V0sM68OSac+KzQ cUn9HBt39i3QP+B6o5R35sRngXurUz8ZRZlAiTEnkRMtHzYmtRmgdarYXXyPTcpC WcXZU/+bv3vMi1d1i4iqFtVp3KMpi9D/TYFDiArFO3ZUgUs6Fx4pLGfKMq5rMkiy HrA5phe6kbK/Nax/NgwnF1FVJVp3BwIFsV8OM/mI9u/LwlWhV6F5EfAnux2HS70t 1ghNyttM14JoquZKXXpaaNWtGVUWJzrtQYmBrD2+uoOswNwznkWZe4Yhi/P03tef /BB/yeFzbe/f28KckhiPQcmvUk1kBnni5bs817Rs1yCi/HcEqCBOCPMpaA== Received: from mx0a-00154901.pphosted.com (mx0a-00154901.pphosted.com [67.231.149.39]) by mx0a-00154904.pphosted.com (PPS) with ESMTPS id 4g76ty226c-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 25 Aug 2026 02:51:57 -0400 (EDT) Received: from pps.filterd (m0133268.ppops.net [127.0.0.1]) by mx0a-00154901.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67P6UCvD2872376; Tue, 25 Aug 2026 02:51:56 -0400 Received: from esapsmtpat10.us.dell.com (esapsmtpat10.us.dell.com [143.166.211.153]) by mx0a-00154901.pphosted.com (PPS) with ESMTPS id 4g91j0jy3f-2 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=FAIL); Tue, 25 Aug 2026 02:51:56 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dell.com; i=@dell.com; q=dns/txt; s=smtpdev1; t=1787640717; x=1819176717; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=I2eM7lZ898NItMJ2Atd2Uis5jVFbDnvth5GUgV9CY/o=; b=G1eG1j4wTWqzOPiHPS+ZNSzXJO6mozXAPoiftn61ST/oXMH7rOuTQulL 8J7W6OjylrnQrswpWl07vytd5f2ppTZ3zek8qY6XrW3LkhxoflWjCMdVc wl4v6uJZT9Xmdy4S3TcKXLMv66lpSmmoCBXXMrCW4yG54DQQ62LanAdep 0UrFuFnGr8KVGrVi8A0VBf70Go/dFCYsSFUC4BxYmd0w6+tYZrFVcJchj IO9kWlyVmCBtJAGzM8aWrKVn9xWnhjqoi+shNm1NrP1ievzJ7YgsaeYvz +EEtdgh+CvSEoo72aQjd4WvsLiMciTyQGvakhhSsu+HWCtnx3U1U5xFV4 w==; X-CSE-ConnectionGUID: NcbP7+P3R1CQA8YMnxvHsA== X-CSE-MsgGUID: /9g1AdjwR7+TOAl0Wxnybg== X-LoopCount0: from 10.94.13.48 X-MS-Exchange-CrossPremises-AuthAs: Internal Received: from w-96j1th4.apac.dell.com (HELO W-96J1TH4.blr.amer.dell.com) ([10.94.13.48]) by esapsmtpat10.us.dell.com with ESMTP/TLS/TLS_AES_256_GCM_SHA384; 25 Aug 2026 06:51:53 +0000 From: Prabhakar Pujeri To: cel@kernel.org, jlayton@kernel.org Cc: neil@brown.name, okorniev@redhat.com, Dai.Ngo@oracle.com, tom@talpey.com, donald.hunter@gmail.com, kuba@kernel.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Prabhakar Pujeri Subject: [PATCH v1 1/3] nfsd: report NFSv4 grace state through Netlink Date: Tue, 25 Aug 2026 06:51:45 +0000 Message-ID: <3fd25e2178458fbb44f57f1b0e068c12a6503d17.1787638668.git.prabhakar.pujeri@dell.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-25_01,2026-08-24_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 adultscore=0 spamscore=0 lowpriorityscore=0 phishscore=0 malwarescore=0 clxscore=1015 bulkscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608250056 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI1MDA1NyBTYWx0ZWRfX6m4SGgVNsnwI W4UXV504ue+0SFT2aGUlOpIpwCXp+YBWoqlgAYiOrhUd6WPznj/8LKF4yED9Ssmbyf+TZ/pkbB2 B0S34YGMXmVocypSDsBmjIIazvStiDd6q61DhiHQERdrAbwdvs4V7tLb2o2kTUe41mCtdZz+KXy 4nlnv4CcwC8uUo4bfVKVDSQfN9xMkXPy/Bef7oCc/raxtkuxMtEW1XoOJJaEfwGd+6sEBduJXxn qbxwHAaEyCx2Lju4oLjDKFe8qZYySuFnPg7Pl+/J6HGCunQII9CiFtDWpGUdf6x5zPyBoz8L09r 5RrXM6iKpHlSwcmQw/KC5f5sbJFHW4/tT46DjA+Drex130iFIVfEIHRkbeWlFv7T4guYRyT2x6M M34BggauGM08ja0U0zK/p3y29w0JYVdSp+V2BRuziBdZjHVU/4vVrFKlrNYWmBRKZ84ZmlHPryW yRiK74Dc8T25CAUKeNA== X-Proofpoint-GUID: TmMnCm8SSi6NTlwIH-SFuH4ByQvnNT-X X-Proofpoint-Spam-Info: AW1haW4tMjYwODI1MDA1NyBTYWx0ZWRfX1S19jYo537Ec vMaCFr5GQrxU6HA5t4hCQfVHERDYL/F6dYpRcRtelWskPMi3f4z2SCinY7xLhIrHHUcrEB8K0g4 hF3D9/TaFkFVjnhOKmUYgyhwmd2GcXQ= X-Proofpoint-ORIG-GUID: TmMnCm8SSi6NTlwIH-SFuH4ByQvnNT-X X-Authority-Analysis: v=2.4 cv=BMGDalQG c=1 sm=1 tr=0 ts=6a8d3b8d cx=c_pps a=j0++y401J6f/BxNAf5EDow==:117 a=zctdXvwhg3EK6xEvKeLW8g==:17 a=Sv0fKeRqtYgA:10 a=ke5jqHz-1hQA:10 a=VkNPw1HP01LnGYTKEx00:22 a=6gNNCFAoQcIphELLPWWu:22 a=sEWawkeXllE7TocFc0N_:22 a=iLNU1ar6AAAA:8 a=lXXOwkYEy2pcZcTpNIYA:9 a=gbU3OgOOxF9bX48Letew:22 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 lowpriorityscore=0 malwarescore=0 clxscore=1015 spamscore=0 priorityscore=1501 adultscore=0 phishscore=0 suspectscore=0 impostorscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608250057 Content-Type: text/plain; charset="utf-8" Operational tooling needs to distinguish a server that is accepting normal NFSv4 state operations from one that is still accepting only recovery requests. The existing Netlink threads query reports server-wide configuration, but recovery state is available only through the nfsd filesystem. Add an in-grace value to the threads-get reply. Return it in every reply so user space can distinguish a server that is not in grace from an older kernel that does not provide the attribute. Signed-off-by: Prabhakar Pujeri --- Documentation/admin-guide/nfs/nfsd-admin-interfaces.rst | 3 +++ Documentation/netlink/specs/nfsd.yaml | 6 ++++++ fs/nfsd/nfsctl.c | 9 ++++++++- include/uapi/linux/nfsd_netlink.h | 1 + 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Documentation/admin-guide/nfs/nfsd-admin-interfaces.rst b/Docu= mentation/admin-guide/nfs/nfsd-admin-interfaces.rst index c05926f79054..35c174000ab3 100644 --- a/Documentation/admin-guide/nfs/nfsd-admin-interfaces.rst +++ b/Documentation/admin-guide/nfs/nfsd-admin-interfaces.rst @@ -25,6 +25,9 @@ udp and one tcp listener at port 2049 (see nfsd_init_sock= s). On startup, nfsd and lockd grace periods start. nfsd is shut down by a wri= te of 0 to nfsd/threads. All locks and state are thrown away at that point. =20 +The ``in-grace`` value in the ``threads-get`` Generic Netlink reply reports +whether the NFSv4 server's recovery grace period is still active. + Between startup and shutdown, the number of threads may be adjusted up or down by additional writes to nfsd/threads or by writes to nfsd/pool_threads. diff --git a/Documentation/netlink/specs/nfsd.yaml b/Documentation/netlink/= specs/nfsd.yaml index 642268819c6f..d01d93f39392 100644 --- a/Documentation/netlink/specs/nfsd.yaml +++ b/Documentation/netlink/specs/nfsd.yaml @@ -130,6 +130,11 @@ attribute-sets: type: binary checks: exact-len: 16 + - + name: in-grace + type: u8 + doc: One while the NFSv4 server is in its recovery grace period, + otherwise zero. - name: version attributes: @@ -464,6 +469,7 @@ operations: - leasetime - scope - min-threads + - in-grace - name: version-set doc: set nfs enabled versions diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 6e63950a99e1..7ea865b372cc 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1775,6 +1775,7 @@ int nfsd_nl_threads_get_doit(struct sk_buff *skb, str= uct genl_info *info) { struct net *net =3D genl_info_net(info); struct nfsd_net *nn =3D net_generic(net, nfsd_net_id); + bool in_grace =3D false; void *hdr; int err; =20 @@ -1790,6 +1791,11 @@ int nfsd_nl_threads_get_doit(struct sk_buff *skb, st= ruct genl_info *info) =20 mutex_lock(&nfsd_mutex); =20 +#ifdef CONFIG_NFSD_V4 + in_grace =3D nfsd_vers(nn, 4, NFSD_TEST) && + test_bit(NFSD_NET_UP, &nn->flags) && + !test_bit(NFSD_NET_GRACE_ENDED, &nn->flags); +#endif err =3D nla_put_u32(skb, NFSD_A_SERVER_GRACETIME, nn->nfsd4_grace) || nla_put_u32(skb, NFSD_A_SERVER_LEASETIME, @@ -1797,7 +1803,8 @@ int nfsd_nl_threads_get_doit(struct sk_buff *skb, str= uct genl_info *info) nla_put_u32(skb, NFSD_A_SERVER_MIN_THREADS, nn->min_threads) || nla_put_string(skb, NFSD_A_SERVER_SCOPE, - nn->nfsd_name); + nn->nfsd_name) || + nla_put_u8(skb, NFSD_A_SERVER_IN_GRACE, in_grace); if (err) goto err_unlock; =20 diff --git a/include/uapi/linux/nfsd_netlink.h b/include/uapi/linux/nfsd_ne= tlink.h index 87da1d0bb21e..e1fc2db00046 100644 --- a/include/uapi/linux/nfsd_netlink.h +++ b/include/uapi/linux/nfsd_netlink.h @@ -84,6 +84,7 @@ enum { NFSD_A_SERVER_SCOPE, NFSD_A_SERVER_MIN_THREADS, NFSD_A_SERVER_FH_KEY, + NFSD_A_SERVER_IN_GRACE, =20 __NFSD_A_SERVER_MAX, NFSD_A_SERVER_MAX =3D (__NFSD_A_SERVER_MAX - 1) --=20 2.54.0 From nobody Mon Sep 28 07:17:05 2026 Received: from mx0b-00154904.pphosted.com (mx0b-00154904.pphosted.com [148.163.137.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8CC6263F5D; Tue, 25 Aug 2026 06:52:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.137.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787640732; cv=none; b=sPn9RNOh+eu4h0Uv8+Opo6h0RHvtbuxbT5yb9fs5fakswrlGBhVzTHIZF4HTnS+SpS3dhz2U36dIzZhrVbIvcfkM1dt8eWsTU/ddX0/F95C8SyoqZtlwA600/lj7LhO7fCdC9ZvqTZk7oVw8dJkOAKyk1OF7Eg5aYarL9gCRFcw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787640732; c=relaxed/simple; bh=k3pQJebpZGPesuVRu/q7CgKG8NWzlzcTOvdVAKylpbs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bym+p4wEtBArVW81X5rcUH5wCZStykl7p6LrPtWowZVkwvRE7SSAqWv4FacEg6WmSClJ4WX5V5Vs9UxE/qGq1lhkNItWCU8jo/3Oc1cbk5DJXS7jYp1+AO6o1hJguX0pUv2+c0vFi7iSnRpttWPrmNLNhdAI/CZqHRI/oF8Y+FU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=dell.com; spf=pass smtp.mailfrom=dell.com; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b=hRgJ+/vU; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b=hkr4/pcP; arc=none smtp.client-ip=148.163.137.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=dell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=dell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b="hRgJ+/vU"; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b="hkr4/pcP" Received: from pps.filterd (m0170397.ppops.net [127.0.0.1]) by mx0b-00154904.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67P2RO4H1134761; Tue, 25 Aug 2026 02:52:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dell.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=smtpout1; bh=nPaxhAG9XnlJ eq70/PMMa1IR+0nXXbC+grpgHYz+NXI=; b=hRgJ+/vUnlUGWXsTxFYX0FeH5R2F 3sSlNWYwkXB0XfykNEN9uJMJpTrcGPY7xAhz1AfZBSyEG5K30nIdsI2dJhUJambR KG1YF6mOVCMC0HUU3Fto7y0h4rt4UzNxXgmkcV8tyNMeQpMSVsX6fKpwzINFrAeJ lLzAQ2RhExwUmIqRcMSlEAM38ZZW1AM7NL0vrpyzFk/6/kTXtBTeVzquRgcJ8wg1 IC9M+/ndDmCN6o1/rUXSN0onUlz+cL08OHS4yAwoxWyGkyWs9EhksiSfUuKUjGy3 wUZ8a739BIW5oAzHWxoAy0FMVrDlXtemlV4rU5qtj+C62zIZlG3F88kPdw== Received: from mx0a-00154901.pphosted.com (mx0a-00154901.pphosted.com [67.231.149.39]) by mx0b-00154904.pphosted.com (PPS) with ESMTPS id 4g74upj9ux-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 25 Aug 2026 02:52:02 -0400 (EDT) Received: from pps.filterd (m0133268.ppops.net [127.0.0.1]) by mx0a-00154901.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67P6UCvG2872376; Tue, 25 Aug 2026 02:52:01 -0400 Received: from esapsmtpat10.us.dell.com (esapsmtpat10.us.dell.com [143.166.211.153]) by mx0a-00154901.pphosted.com (PPS) with ESMTPS id 4g91j0jy3f-3 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=FAIL); Tue, 25 Aug 2026 02:52:01 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dell.com; i=@dell.com; q=dns/txt; s=smtpdev1; t=1787640722; x=1819176722; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nPaxhAG9XnlJeq70/PMMa1IR+0nXXbC+grpgHYz+NXI=; b=hkr4/pcPyIb7YNJmKghdJjkwemF6FI/sLBeBwXGzUS9x+AuqNKQVIiJK qF0rvuyNaQpL4zd9vWqRtI8U3LI8MbD3kQ1PxUBP3okyJcXDSX0qf62SN Ne1Mk5MOT9+pVUaF3jpwAzOxofta9hU+WM1d/I/JIgLkPH4UOctFZ2Ww9 d0yrCeHqtAC7Id4gF7GRI/q3do7gSDY/KTcctHypvPVEAOTxwZtZElHl/ YtGK3Qlt7xStquvZUDMQ5J7Au9WEIbVpJliHT8fKm+p11K+jliMuWprbO /WKAx1zDQkBQee5fEMX0HultplsN0wBBwSAOufoafiMz4ZfQ6vhFalrEW g==; X-CSE-ConnectionGUID: Kv3tDSn/TsCtb74XsIWo+Q== X-CSE-MsgGUID: XMTik6iFQF6RfGtKNrobDw== X-LoopCount0: from 10.94.13.48 X-MS-Exchange-CrossPremises-AuthAs: Internal Received: from w-96j1th4.apac.dell.com (HELO W-96J1TH4.blr.amer.dell.com) ([10.94.13.48]) by esapsmtpat10.us.dell.com with ESMTP/TLS/TLS_AES_256_GCM_SHA384; 25 Aug 2026 06:51:57 +0000 From: Prabhakar Pujeri To: cel@kernel.org, jlayton@kernel.org Cc: neil@brown.name, okorniev@redhat.com, Dai.Ngo@oracle.com, tom@talpey.com, donald.hunter@gmail.com, kuba@kernel.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Prabhakar Pujeri Subject: [PATCH v1 2/3] nfsd: add a Netlink dump of NFSv4 clients Date: Tue, 25 Aug 2026 06:51:46 +0000 Message-ID: <6b42a390ce3ea9a5930e2704137fd435c6f7d27e.1787638668.git.prabhakar.pujeri@dell.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-25_01,2026-08-24_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 adultscore=0 spamscore=0 lowpriorityscore=0 phishscore=0 malwarescore=0 clxscore=1015 bulkscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608250056 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI1MDA1NyBTYWx0ZWRfXwoHVuYPdwuM0 5xQ9XOR4D//GrLiwo4sCRJr7pcgQV0Igm5aMwKV9q5he1uiUc1yJvmnOQd/p/ztNVPEVWoF/QVy 0DkHU2j5YjhO7qfGhgjo+CCXXWJfs0PdErSs8tbUtQqMZZUNy7st7sHBNCA2/QMtZRR8vinNXah tMZ/xW6rfyQt5lxP9DjFvlOgPVgGudhG/hHtAkczRR9WF/cMyf0PtdXZrElVeCUaawUS7V98sM1 UYoXhcjehyD5zlrZTnG4JHhGEAk7oFin0NUJHA4gTOwA0ebHQ5iNA3oIrw1SRU6SlUn1FhgAzxD slJs7S5JTTjFeewFPmhQrTw00XXYhUWqhs01Eqy9k9LgsEsGUzFxSUK61nDBCEMio25JLln2Qkr 6F/MoJDGxZwySJdmpH+i2I5cjtek99OXgGf0NYq0FmnYL7H0GPtM+GFv8IfKzxEcEwI4mBxe+N0 ZkIaPhxYuPLg0qHNXsg== X-Proofpoint-GUID: XiTf5o7TXopADOlBAcZygqPyYtsXkh_G X-Proofpoint-ORIG-GUID: XiTf5o7TXopADOlBAcZygqPyYtsXkh_G X-Authority-Analysis: v=2.4 cv=dtDrzVg4 c=1 sm=1 tr=0 ts=6a8d3b92 cx=c_pps a=j0++y401J6f/BxNAf5EDow==:117 a=zctdXvwhg3EK6xEvKeLW8g==:17 a=Sv0fKeRqtYgA:10 a=ke5jqHz-1hQA:10 a=VkNPw1HP01LnGYTKEx00:22 a=6gNNCFAoQcIphELLPWWu:22 a=U3ti1ie9CgboSd2qXsAw:22 a=iLNU1ar6AAAA:8 a=Qh7K5O9fiLzXO3WRn7YA:9 a=gbU3OgOOxF9bX48Letew:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwODI1MDA1NyBTYWx0ZWRfX3YAFWc1a08ZP 0CBRg7zvbSps7ACvUUqqH05Xb/286pLZ++65cl0/oE+lnZ2t4wCfupyMiy/crUsgNdBrt2/VcEF 8jIfwCC4MgtncYYVVt2FJcDrjsMWfTw= X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 clxscore=1015 adultscore=0 spamscore=0 malwarescore=0 suspectscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608250057 Content-Type: text/plain; charset="utf-8" Administrators currently have to walk one nfsd filesystem directory per client to correlate basic NFSv4 identity, lease, and callback information. That interface is useful for detailed inspection, but it is awkward for monitoring tools and provides no atomic way to enumerate the client set. Add a privileged client-get dump to the nfsd Generic Netlink family. Emit one bounded message per confirmed or unconfirmed client with its server-generated client ID, peer address, minor version, client and callback states, signed lease time remaining, and RECLAIM_COMPLETE status. Pin each client while taking a snapshot, protect mutable lease and confirmation fields with the per-net client lock, and serialize against server shutdown with nfsd_mutex. Netlink dump cursors track the table, bucket, and position; client churn can still cause a best-effort snapshot, which is documented. Leave the existing nfsd filesystem interface unchanged. Signed-off-by: Prabhakar Pujeri --- .../admin-guide/nfs/nfsd-admin-interfaces.rst | 15 ++ Documentation/netlink/specs/nfsd.yaml | 75 +++++++ fs/nfsd/netlink.c | 5 + fs/nfsd/netlink.h | 1 + fs/nfsd/nfs4ctl.h | 10 + fs/nfsd/nfs4state.c | 200 ++++++++++++++++++ fs/nfsd/nfsctl.c | 13 ++ include/uapi/linux/nfsd_netlink.h | 35 +++ 8 files changed, 354 insertions(+) diff --git a/Documentation/admin-guide/nfs/nfsd-admin-interfaces.rst b/Docu= mentation/admin-guide/nfs/nfsd-admin-interfaces.rst index 35c174000ab3..bd7a8f71592c 100644 --- a/Documentation/admin-guide/nfs/nfsd-admin-interfaces.rst +++ b/Documentation/admin-guide/nfs/nfsd-admin-interfaces.rst @@ -32,6 +32,21 @@ Between startup and shutdown, the number of threads may = be adjusted up or down by additional writes to nfsd/threads or by writes to nfsd/pool_threads. =20 +NFSv4 client visibility +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The privileged ``client-get`` dump in the ``nfsd`` Generic Netlink family +emits one message for each NFSv4 client. Each message identifies the clie= nt +by its server-generated client ID and transport address, then reports its +minor version, client and callback states, signed lease time remaining, and +whether an NFSv4.1 or later client sent RECLAIM_COMPLETE. + +The dump is a best-effort snapshot; clients can change between messages. + +The existing ``/proc/fs/nfsd/clients/`` files remain available for inspect= ion. +The ``states`` file contains individual stateids, and writing ``expire`` to +``ctl`` forcibly removes the client and all state it owns. + For more detail about files under nfsd/ and what they control, see fs/nfsd/nfsctl.c; most of them have detailed comments. =20 diff --git a/Documentation/netlink/specs/nfsd.yaml b/Documentation/netlink/= specs/nfsd.yaml index d01d93f39392..5df329ebe0b1 100644 --- a/Documentation/netlink/specs/nfsd.yaml +++ b/Documentation/netlink/specs/nfsd.yaml @@ -42,6 +42,24 @@ definitions: - none - tls - mtls + - + type: enum + name: client-state + doc: State of an NFSv4 client record. + entries: + - unconfirmed + - active + - courtesy + - expirable + - + type: enum + name: callback-state + doc: State of an NFSv4 client's callback channel. + entries: + - up + - unknown + - down + - fault =20 attribute-sets: - @@ -420,6 +438,48 @@ attribute-sets: type: nest nested-attributes: server-proc-entry multi-attr: true + - + name: client + attributes: + - + name: clientid + type: u64 + doc: >- + Server-generated NFSv4 client ID, with the boot value in the upp= er + 32 bits and the per-boot ID in the lower 32 bits. + - + name: pad + type: pad + - + name: address + type: binary + doc: >- + Transport peer address recorded when the client was created, as + struct sockaddr_in or struct sockaddr_in6. + checks: + min-len: 16 + - + name: minor-version + type: u32 + doc: Negotiated NFSv4 minor version. + - + name: state + type: u32 + enum: client-state + doc: Confirmation and courtesy-state status of the client record. + - + name: lease-remaining + type: s64 + doc: Signed seconds until the client's lease expires; negative mea= ns overdue. + - + name: reclaim-complete + type: flag + doc: The NFSv4.1 or later client sent RECLAIM_COMPLETE. + - + name: callback-state + type: u32 + enum: callback-state + doc: Health of the client's callback channel. =20 operations: list: @@ -633,6 +693,21 @@ operations: - proc4-ops - proc4ops-ops - proc4cb-ops + - + name: client-get + doc: dump NFSv4 clients + attribute-set: client + flags: [admin-perm] + dump: + reply: + attributes: + - clientid + - address + - minor-version + - state + - lease-remaining + - reclaim-complete + - callback-state =20 mcast-groups: list: diff --git a/fs/nfsd/netlink.c b/fs/nfsd/netlink.c index eba8b353f412..48bc499136b5 100644 --- a/fs/nfsd/netlink.c +++ b/fs/nfsd/netlink.c @@ -230,6 +230,11 @@ static const struct genl_split_ops nfsd_nl_ops[] =3D { .dumpit =3D nfsd_nl_server_stats_get_dumpit, .flags =3D GENL_CMD_CAP_DUMP, }, + { + .cmd =3D NFSD_CMD_CLIENT_GET, + .dumpit =3D nfsd_nl_client_get_dumpit, + .flags =3D GENL_ADMIN_PERM | GENL_CMD_CAP_DUMP, + }, }; =20 static const struct genl_multicast_group nfsd_nl_mcgrps[] =3D { diff --git a/fs/nfsd/netlink.h b/fs/nfsd/netlink.h index 027e2953db26..de7593e64082 100644 --- a/fs/nfsd/netlink.h +++ b/fs/nfsd/netlink.h @@ -44,6 +44,7 @@ int nfsd_nl_unlock_filesystem_doit(struct sk_buff *skb, s= truct genl_info *info); int nfsd_nl_unlock_export_doit(struct sk_buff *skb, struct genl_info *info= ); int nfsd_nl_server_stats_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb); +int nfsd_nl_client_get_dumpit(struct sk_buff *skb, struct netlink_callback= *cb); =20 enum { NFSD_NLGRP_NONE, diff --git a/fs/nfsd/nfs4ctl.h b/fs/nfsd/nfs4ctl.h index bcec4c4ef1d5..44cbb0fac588 100644 --- a/fs/nfsd/nfs4ctl.h +++ b/fs/nfsd/nfs4ctl.h @@ -20,8 +20,10 @@ struct net; struct inode; struct dentry; +struct sk_buff; struct svc_rqst; struct nfsd_net; +struct netlink_callback; =20 #ifdef CONFIG_NFSD_V4 extern unsigned long max_delegations; @@ -37,6 +39,8 @@ bool nfsd4_spo_must_allow(struct svc_rqst *rqstp); int nfsd4_create_laundry_wq(void); void nfsd4_destroy_laundry_wq(void); bool nfsd_wait_for_delegreturn(struct svc_rqst *rqstp, struct inode *inode= ); +int nfsd4_nl_client_get_dumpit(struct sk_buff *skb, + struct netlink_callback *cb); =20 extern int nfsd4_is_junction(struct dentry *dentry); extern int register_cld_notifier(void); @@ -68,6 +72,12 @@ static inline bool nfsd_wait_for_delegreturn(struct svc_= rqst *rqstp, return false; } =20 +static inline int nfsd4_nl_client_get_dumpit(struct sk_buff *skb, + struct netlink_callback *cb) +{ + return 0; +} + static inline int nfsd4_is_junction(struct dentry *dentry) { return 0; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2c1b8b2cbbb5..9add35dfb58b 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -59,6 +59,7 @@ #include "pnfs.h" #include "filecache.h" #include "nfs4xdr_gen.h" +#include "netlink.h" #include "trace.h" =20 #define NFSDDBG_FACILITY NFSDDBG_PROC @@ -3232,6 +3233,205 @@ static const char *cb_state2str(int state) return "UNDEFINED"; } =20 +enum nfsd4_nl_client_table { + NFSD4_NL_CLIENT_CONFIRMED, + NFSD4_NL_CLIENT_UNCONFIRMED, + NFSD4_NL_CLIENT_DONE, +}; + +struct nfsd4_nl_client { + struct sockaddr_storage address; + u64 clientid; + s64 lease_remaining; + u32 minor_version; + u32 state; + u32 callback_state; + bool reclaim_complete; +}; + +static u32 nfsd4_nl_client_state(bool confirmed, unsigned int state) +{ + if (!confirmed) + return NFSD_CLIENT_STATE_UNCONFIRMED; + + switch (state) { + case NFSD4_COURTESY: + return NFSD_CLIENT_STATE_COURTESY; + case NFSD4_EXPIRABLE: + return NFSD_CLIENT_STATE_EXPIRABLE; + default: + return NFSD_CLIENT_STATE_ACTIVE; + } +} + +static u32 nfsd4_nl_callback_state(int state) +{ + switch (state) { + case NFSD4_CB_UP: + return NFSD_CALLBACK_STATE_UP; + case NFSD4_CB_DOWN: + return NFSD_CALLBACK_STATE_DOWN; + case NFSD4_CB_FAULT: + return NFSD_CALLBACK_STATE_FAULT; + default: + return NFSD_CALLBACK_STATE_UNKNOWN; + } +} + +static struct nfs4_client * +nfsd4_nl_get_client(struct nfsd_net *nn, enum nfsd4_nl_client_table table, + unsigned long bucket, unsigned long skip) +{ + struct nfs4_client *clp =3D NULL; + struct nfs4_client *pos; + struct list_head *head; + unsigned long index =3D 0; + + lockdep_assert_held(&nfsd_mutex); + + if (table =3D=3D NFSD4_NL_CLIENT_CONFIRMED) + head =3D &nn->conf_id_hashtbl[bucket]; + else + head =3D &nn->unconf_id_hashtbl[bucket]; + + spin_lock(&nn->client_lock); + list_for_each_entry(pos, head, cl_idhash) { + if (index++ !=3D skip) + continue; + kref_get(&pos->cl_nfsdfs.cl_ref); + clp =3D pos; + break; + } + spin_unlock(&nn->client_lock); + return clp; +} + +static void nfsd4_nl_client_snapshot(struct nfsd_net *nn, + struct nfs4_client *clp, + struct nfsd4_nl_client *client) +{ + unsigned int state; + time64_t last_renew; + bool confirmed; + + spin_lock(&nn->client_lock); + last_renew =3D clp->cl_time; + confirmed =3D test_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags); + state =3D READ_ONCE(clp->cl_state); + spin_unlock(&nn->client_lock); + + memcpy(&client->address, &clp->cl_addr, sizeof(client->address)); + client->clientid =3D (u64)clp->cl_clientid.cl_boot << 32 | + clp->cl_clientid.cl_id; + client->lease_remaining =3D last_renew ? + last_renew + READ_ONCE(nn->nfsd4_lease) - + ktime_get_boottime_seconds() : 0; + client->minor_version =3D clp->cl_minorversion; + client->state =3D nfsd4_nl_client_state(confirmed, state); + client->callback_state =3D + nfsd4_nl_callback_state(READ_ONCE(clp->cl_cb_state)); + client->reclaim_complete =3D + test_bit(NFSD4_CLIENT_RECLAIM_COMPLETE, &clp->cl_flags); +} + +static int nfsd4_nl_client_compose_msg(struct sk_buff *skb, + struct netlink_callback *cb, + const struct nfsd4_nl_client *client) +{ + void *hdr; + + hdr =3D genlmsg_put(skb, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, &nfsd_nl_family, NLM_F_MULTI, + NFSD_CMD_CLIENT_GET); + if (!hdr) + return -EMSGSIZE; + + if (nla_put_u64_64bit(skb, NFSD_A_CLIENT_CLIENTID, client->clientid, + NFSD_A_CLIENT_PAD) || + nla_put(skb, NFSD_A_CLIENT_ADDRESS, + svc_addr_len((const struct sockaddr *)&client->address), + &client->address) || + nla_put_u32(skb, NFSD_A_CLIENT_MINOR_VERSION, + client->minor_version) || + nla_put_u32(skb, NFSD_A_CLIENT_STATE, client->state) || + nla_put_s64(skb, NFSD_A_CLIENT_LEASE_REMAINING, + client->lease_remaining, NFSD_A_CLIENT_PAD) || + (client->reclaim_complete && + nla_put_flag(skb, NFSD_A_CLIENT_RECLAIM_COMPLETE)) || + nla_put_u32(skb, NFSD_A_CLIENT_CALLBACK_STATE, + client->callback_state)) + goto err_cancel; + + genlmsg_end(skb, hdr); + return 0; + +err_cancel: + genlmsg_cancel(skb, hdr); + return -EMSGSIZE; +} + +/** + * nfsd4_nl_client_get_dumpit - dump NFSv4 client information + * @skb: reply buffer + * @cb: netlink metadata and command arguments + * + * One netlink message is emitted for each client. cb->args tracks the cli= ent + * table, hash bucket, and offset within that bucket. The dump is a best-e= ffort + * snapshot because clients can be added, confirmed, or removed between ca= lls. + * + * Returns the size of the reply or a negative errno. + */ +int nfsd4_nl_client_get_dumpit(struct sk_buff *skb, + struct netlink_callback *cb) +{ + struct nfsd4_nl_client client; + struct nfs4_client *clp; + struct nfsd_net *nn; + struct net *net; + int ret =3D 0; + + net =3D sock_net(skb->sk); + nn =3D net_generic(net, nfsd_net_id); + mutex_lock(&nfsd_mutex); + if (!test_bit(NFSD_NET_UP, &nn->flags)) { + ret =3D -ENODEV; + goto out_unlock; + } + + while (cb->args[0] < NFSD4_NL_CLIENT_DONE) { + if (cb->args[1] >=3D CLIENT_HASH_SIZE) { + cb->args[0]++; + cb->args[1] =3D 0; + cb->args[2] =3D 0; + continue; + } + + clp =3D nfsd4_nl_get_client(nn, cb->args[0], cb->args[1], + cb->args[2]); + if (!clp) { + cb->args[1]++; + cb->args[2] =3D 0; + continue; + } + + memset(&client, 0, sizeof(client)); + nfsd4_nl_client_snapshot(nn, clp, &client); + ret =3D nfsd4_nl_client_compose_msg(skb, cb, &client); + nfsd4_put_client(clp); + if (ret) { + if (skb->len) + ret =3D skb->len; + goto out_unlock; + } + cb->args[2]++; + } + ret =3D skb->len; + +out_unlock: + mutex_unlock(&nfsd_mutex); + return ret; +} + static int client_info_show(struct seq_file *m, void *v) { struct inode *inode =3D file_inode(m->file); diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 7ea865b372cc..5079f74d3d65 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1634,6 +1634,19 @@ int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *sk= b, return ret; } =20 +/** + * nfsd_nl_client_get_dumpit - dump NFSv4 client information + * @skb: reply buffer + * @cb: netlink metadata and command arguments + * + * Returns the size of the reply or a negative errno. + */ +int nfsd_nl_client_get_dumpit(struct sk_buff *skb, + struct netlink_callback *cb) +{ + return nfsd4_nl_client_get_dumpit(skb, cb); +} + /** * nfsd_nl_fh_key_set - helper to copy fh_key from userspace * @attr: nlattr NFSD_A_SERVER_FH_KEY diff --git a/include/uapi/linux/nfsd_netlink.h b/include/uapi/linux/nfsd_ne= tlink.h index e1fc2db00046..ae495382092d 100644 --- a/include/uapi/linux/nfsd_netlink.h +++ b/include/uapi/linux/nfsd_netlink.h @@ -50,6 +50,26 @@ enum nfsd_xprtsec_mode { NFSD_XPRTSEC_MODE_MTLS =3D 4, }; =20 +/* + * State of an NFSv4 client record. + */ +enum nfsd_client_state { + NFSD_CLIENT_STATE_UNCONFIRMED, + NFSD_CLIENT_STATE_ACTIVE, + NFSD_CLIENT_STATE_COURTESY, + NFSD_CLIENT_STATE_EXPIRABLE, +}; + +/* + * State of an NFSv4 client's callback channel. + */ +enum nfsd_callback_state { + NFSD_CALLBACK_STATE_UP, + NFSD_CALLBACK_STATE_UNKNOWN, + NFSD_CALLBACK_STATE_DOWN, + NFSD_CALLBACK_STATE_FAULT, +}; + enum { NFSD_A_CACHE_NOTIFY_CACHE_TYPE =3D 1, =20 @@ -261,6 +281,20 @@ enum { NFSD_A_SERVER_STATS_MAX =3D (__NFSD_A_SERVER_STATS_MAX - 1) }; =20 +enum { + NFSD_A_CLIENT_CLIENTID =3D 1, + NFSD_A_CLIENT_PAD, + NFSD_A_CLIENT_ADDRESS, + NFSD_A_CLIENT_MINOR_VERSION, + NFSD_A_CLIENT_STATE, + NFSD_A_CLIENT_LEASE_REMAINING, + NFSD_A_CLIENT_RECLAIM_COMPLETE, + NFSD_A_CLIENT_CALLBACK_STATE, + + __NFSD_A_CLIENT_MAX, + NFSD_A_CLIENT_MAX =3D (__NFSD_A_CLIENT_MAX - 1) +}; + enum { NFSD_CMD_RPC_STATUS_GET =3D 1, NFSD_CMD_THREADS_SET, @@ -281,6 +315,7 @@ enum { NFSD_CMD_UNLOCK_FILESYSTEM, NFSD_CMD_UNLOCK_EXPORT, NFSD_CMD_SERVER_STATS_GET, + NFSD_CMD_CLIENT_GET, =20 __NFSD_CMD_MAX, NFSD_CMD_MAX =3D (__NFSD_CMD_MAX - 1) --=20 2.54.0 From nobody Mon Sep 28 07:17:05 2026 Received: from mx0b-00154904.pphosted.com (mx0b-00154904.pphosted.com [148.163.137.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 629D33CF1F9; Tue, 25 Aug 2026 06:52:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.137.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787640735; cv=none; b=qDGOLKaAitOnDQXvC1n+aXJSFkPg51LLVcolsCevU4l1ypiiggqmnpWKUBhDjqsn09EsgRsL2y3FW394pOf/zKdG2UA7NopH77QkdGK4eHtZENPjPcYZTMZGY4EMN6u7FwBhBl7IWiHp9pSlr2B/XHo3tJksw1RDM7PTgd61Hbw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787640735; c=relaxed/simple; bh=E+dKF71NFjds38t5hc0LkKgCqKsXkmz3y63QTXY+YZk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=P1bXGIsqV16MVDsH/CQMLtWIzM1Ok5nftLZFLdGjSSBuUfydi5HndVDsJNRwh0VhixEALGa/Kq7X3mDpP7aL1CinrKNNMAloNInG8Eik7locZ8Hzum630URvaCIfwPrH47nWtxnmBz7B1CpkqplROw7afFzxxQTilLkK0ISuMyE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=dell.com; spf=pass smtp.mailfrom=dell.com; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b=RvGb2Sn/; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b=OsAlwkhW; arc=none smtp.client-ip=148.163.137.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=dell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=dell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b="RvGb2Sn/"; dkim=pass (2048-bit key) header.d=dell.com header.i=@dell.com header.b="OsAlwkhW" Received: from pps.filterd (m0170395.ppops.net [127.0.0.1]) by mx0b-00154904.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67P2RNXw1438105; Tue, 25 Aug 2026 02:52:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dell.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=smtpout1; bh=Wn7gjBS6uQ38 2HqFdF+VtWXb/8VPHvRjM1GM4BY055U=; b=RvGb2Sn/nAENTVz7bout7DMeEAvV 11KVZ2dXS1YQBHs7MiMbU+2FY88043mnM9ihBuDpfKmVWxq6IFwhPIcc/b9m9GJb z34WIQIO/y/FNX3750YxsOWTdiwsJzyr0DROu2/RgTRi0jdlNdD4TZVaoLJlcr4z dESx6PXVlYa/iM10/6PiTio5NDACOjydep4UK3mWuZeDyvXS6kFs1hCijiIVVCDQ zDElbbY0HbWrf5cpwHS/nlOlLsJoJKgvY162aUl9vD50eR4L108+JP7eKwSabiGz W+nvx8lflcyPNxxrO6llLka3xM3AruIEj+7Hlsd4lFldkAKuE320Dybpkw== Received: from mx0a-00154901.pphosted.com (mx0a-00154901.pphosted.com [67.231.149.39]) by mx0b-00154904.pphosted.com (PPS) with ESMTPS id 4g78egstdn-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 25 Aug 2026 02:52:05 -0400 (EDT) Received: from pps.filterd (m0133268.ppops.net [127.0.0.1]) by mx0a-00154901.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67P6UCvH2872376; Tue, 25 Aug 2026 02:52:05 -0400 Received: from esapsmtpat10.us.dell.com (esapsmtpat10.us.dell.com [143.166.211.153]) by mx0a-00154901.pphosted.com (PPS) with ESMTPS id 4g91j0jy3f-4 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=FAIL); Tue, 25 Aug 2026 02:52:04 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dell.com; i=@dell.com; q=dns/txt; s=smtpdev1; t=1787640725; x=1819176725; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Wn7gjBS6uQ382HqFdF+VtWXb/8VPHvRjM1GM4BY055U=; b=OsAlwkhWPUi40wGkPRqy8RSSqFP5GvZdiDzxs/brXhd2b5xQDYSq4nbN HyPfq2XdJx1JirpeAqDeElkI2IBQmj0OnhLny9/qB9ZZxuVitdumTXRHG 2S0h8sAkrStAOBRWA7ioHml1tkYXsIRnZDUfpD7T4M4KEJYGfnu+QLoyN QzPykmbLXnIvaAjo3HsAG4+/6tbMXCY/6nFF2J1sKWPeJPv3HWkVuMZil +x9tpbJc6zVCyJbHH6CGXLQKPjyiLrcMrcPcSMRE3eJfy9paSoa3wYt8F chyOOIEa85bm1K2xwa2LLd+xixybGi4+1qeJ/Df4aczFjGl5/xz8/hT5t g==; X-CSE-ConnectionGUID: uZekLzY/S7mspt8QAKnHGg== X-CSE-MsgGUID: D43lxPSSTIq2Ig6m/kswTQ== X-LoopCount0: from 10.94.13.48 X-MS-Exchange-CrossPremises-AuthAs: Internal Received: from w-96j1th4.apac.dell.com (HELO W-96J1TH4.blr.amer.dell.com) ([10.94.13.48]) by esapsmtpat10.us.dell.com with ESMTP/TLS/TLS_AES_256_GCM_SHA384; 25 Aug 2026 06:52:01 +0000 From: Prabhakar Pujeri To: cel@kernel.org, jlayton@kernel.org Cc: neil@brown.name, okorniev@redhat.com, Dai.Ngo@oracle.com, tom@talpey.com, donald.hunter@gmail.com, kuba@kernel.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Prabhakar Pujeri Subject: [PATCH v1 3/3] nfsd: report per-client NFSv4 state usage through Netlink Date: Tue, 25 Aug 2026 06:51:47 +0000 Message-ID: <245a1ee42d054e280629c9640c8d8225b45639d0.1787638668.git.prabhakar.pujeri@dell.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-25_01,2026-08-24_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 adultscore=0 spamscore=0 lowpriorityscore=0 phishscore=0 malwarescore=0 clxscore=1015 bulkscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608250056 X-Proofpoint-ORIG-GUID: lHa2ODKiB1iiX5lFoLWMMGuyYVOw0zmN X-Proofpoint-Spam-Info: AW1haW4tMjYwODI1MDA1NyBTYWx0ZWRfX3l1I51h/KkYB mwg1moL2vkqs+Koygkmj03Ku+qsWcjPpVb/M0BMpytK2LU7LocO55conz/FvKP1wZnOmBmKPAdF WqhhA44N+iI+fr9zkGVsfoDaLn1tvOQ= X-Proofpoint-GUID: lHa2ODKiB1iiX5lFoLWMMGuyYVOw0zmN X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI1MDA1NyBTYWx0ZWRfX6IHVlKmlwI3I xfQr7IbnjiaOuySbBKyAwGZg9OBuYEg3F5n/rABTRyGCJ85r8QLw64FUOM8COv4rHQPvayoGbNd pwxGMcoxM6B9vO5rsDPa6At66x4jdv+4sFv7KrItoWOd4iiNHRufD2oDTY7C9VYUCv/2b7+paqq c24m4kM5RjmhbtbzgAGyN+UX/O/sxZmeiMzhyhcWOaOAVbO/ogkUJVRgUgASaezz3hkkw2oZnRa vH/D/0P40iTMneAdp4p0CjHXSFK1v6XnHuBhNei9MR0z3ZwffZNWz9vViRpPAYXZQiuisWB6It7 TddxVvYBsNYXf+7oDzlkCxRqZz9TtHhEh+u+cStsAlMrOw/UdOh+Utw8cYXxaD4x8IdGB8Y3dGW EhYU0zklOCQfYPqZfsiIJgv7bX+jz0qrEJImHc52L/VlPm+8+1kWgrAde4RqtNXb8Mio9+9gcap ZjfHsK3ZL1f1qzSj2BQ== X-Authority-Analysis: v=2.4 cv=Z6Hc2nRA c=1 sm=1 tr=0 ts=6a8d3b96 cx=c_pps a=j0++y401J6f/BxNAf5EDow==:117 a=zctdXvwhg3EK6xEvKeLW8g==:17 a=Sv0fKeRqtYgA:10 a=ke5jqHz-1hQA:10 a=VkNPw1HP01LnGYTKEx00:22 a=6gNNCFAoQcIphELLPWWu:22 a=Qy6CKLcU0MZ4grw4BCWD:22 a=iLNU1ar6AAAA:8 a=IUJZ_EN-PaMBYXuBGKEA:9 a=gbU3OgOOxF9bX48Letew:22 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 clxscore=1015 priorityscore=1501 impostorscore=0 phishscore=0 bulkscore=0 malwarescore=0 lowpriorityscore=0 adultscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608250057 Content-Type: text/plain; charset="utf-8" A client can retain substantial server-side state even when its lease and callback channel look healthy. Monitoring tools need compact per-client totals to identify which client owns that state before doing a detailed inspection through the nfsd filesystem. Extend client-get replies with separate counts for sessions and open, lock, delegation, and layout stateid records. A lock stateid represents a lock-owner/file pair and can cover multiple byte-range locks, so document that these are record counts rather than protocol operation or byte-range counts. Walk both the session list and stateid IDR under cl_lock. free_client() already detaches its session list under that lock, so a client pinned by the dump cannot race this traversal with session teardown. Signed-off-by: Prabhakar Pujeri --- .../admin-guide/nfs/nfsd-admin-interfaces.rst | 4 ++ Documentation/netlink/specs/nfsd.yaml | 27 ++++++++++++- fs/nfsd/nfs4state.c | 40 ++++++++++++++++++- include/uapi/linux/nfsd_netlink.h | 5 +++ 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/Documentation/admin-guide/nfs/nfsd-admin-interfaces.rst b/Docu= mentation/admin-guide/nfs/nfsd-admin-interfaces.rst index bd7a8f71592c..076b20f4bf6a 100644 --- a/Documentation/admin-guide/nfs/nfsd-admin-interfaces.rst +++ b/Documentation/admin-guide/nfs/nfsd-admin-interfaces.rst @@ -41,6 +41,10 @@ by its server-generated client ID and transport address,= then reports its minor version, client and callback states, signed lease time remaining, and whether an NFSv4.1 or later client sent RECLAIM_COMPLETE. =20 +The dump also reports separate counts for sessions and open, lock, delegat= ion, +and layout stateids. A lock stateid represents state for one lock owner a= nd +file, not necessarily one byte-range lock. + The dump is a best-effort snapshot; clients can change between messages. =20 The existing ``/proc/fs/nfsd/clients/`` files remain available for inspect= ion. diff --git a/Documentation/netlink/specs/nfsd.yaml b/Documentation/netlink/= specs/nfsd.yaml index 5df329ebe0b1..1707de076d43 100644 --- a/Documentation/netlink/specs/nfsd.yaml +++ b/Documentation/netlink/specs/nfsd.yaml @@ -480,6 +480,26 @@ attribute-sets: type: u32 enum: callback-state doc: Health of the client's callback channel. + - + name: sessions + type: u32 + doc: Number of NFSv4.1 or later sessions owned by the client. + - + name: open-stateids + type: u32 + doc: Number of open stateid records owned by the client. + - + name: lock-stateids + type: u32 + doc: Number of lock-owner/file stateid records, not byte-range loc= ks. + - + name: delegation-stateids + type: u32 + doc: Number of delegation stateid records owned by the client. + - + name: layout-stateids + type: u32 + doc: Number of pNFS layout stateid records owned by the client. =20 operations: list: @@ -695,7 +715,7 @@ operations: - proc4cb-ops - name: client-get - doc: dump NFSv4 clients + doc: dump NFSv4 clients and their current state usage attribute-set: client flags: [admin-perm] dump: @@ -708,6 +728,11 @@ operations: - lease-remaining - reclaim-complete - callback-state + - sessions + - open-stateids + - lock-stateids + - delegation-stateids + - layout-stateids =20 mcast-groups: list: diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 9add35dfb58b..f023cfff818d 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2822,7 +2822,7 @@ free_client(struct nfs4_client *clp) { LIST_HEAD(reaplist); =20 - /* client_info_show() walks cl_sessions under cl_lock */ + /* Client reporting walks cl_sessions under cl_lock. */ spin_lock(&clp->cl_lock); list_splice_init(&clp->cl_sessions, &reaplist); spin_unlock(&clp->cl_lock); @@ -3246,6 +3246,11 @@ struct nfsd4_nl_client { u32 minor_version; u32 state; u32 callback_state; + u32 sessions; + u32 open_stateids; + u32 lock_stateids; + u32 delegation_stateids; + u32 layout_stateids; bool reclaim_complete; }; =20 @@ -3310,6 +3315,8 @@ static void nfsd4_nl_client_snapshot(struct nfsd_net = *nn, struct nfs4_client *clp, struct nfsd4_nl_client *client) { + struct nfs4_stid *stid; + unsigned long id, tmp; unsigned int state; time64_t last_renew; bool confirmed; @@ -3332,6 +3339,26 @@ static void nfsd4_nl_client_snapshot(struct nfsd_net= *nn, nfsd4_nl_callback_state(READ_ONCE(clp->cl_cb_state)); client->reclaim_complete =3D test_bit(NFSD4_CLIENT_RECLAIM_COMPLETE, &clp->cl_flags); + + spin_lock(&clp->cl_lock); + client->sessions =3D list_count_nodes(&clp->cl_sessions); + idr_for_each_entry_ul(&clp->cl_stateids, stid, tmp, id) { + switch (stid->sc_type) { + case SC_TYPE_OPEN: + client->open_stateids++; + break; + case SC_TYPE_LOCK: + client->lock_stateids++; + break; + case SC_TYPE_DELEG: + client->delegation_stateids++; + break; + case SC_TYPE_LAYOUT: + client->layout_stateids++; + break; + } + } + spin_unlock(&clp->cl_lock); } =20 static int nfsd4_nl_client_compose_msg(struct sk_buff *skb, @@ -3359,7 +3386,16 @@ static int nfsd4_nl_client_compose_msg(struct sk_buf= f *skb, (client->reclaim_complete && nla_put_flag(skb, NFSD_A_CLIENT_RECLAIM_COMPLETE)) || nla_put_u32(skb, NFSD_A_CLIENT_CALLBACK_STATE, - client->callback_state)) + client->callback_state) || + nla_put_u32(skb, NFSD_A_CLIENT_SESSIONS, client->sessions) || + nla_put_u32(skb, NFSD_A_CLIENT_OPEN_STATEIDS, + client->open_stateids) || + nla_put_u32(skb, NFSD_A_CLIENT_LOCK_STATEIDS, + client->lock_stateids) || + nla_put_u32(skb, NFSD_A_CLIENT_DELEGATION_STATEIDS, + client->delegation_stateids) || + nla_put_u32(skb, NFSD_A_CLIENT_LAYOUT_STATEIDS, + client->layout_stateids)) goto err_cancel; =20 genlmsg_end(skb, hdr); diff --git a/include/uapi/linux/nfsd_netlink.h b/include/uapi/linux/nfsd_ne= tlink.h index ae495382092d..49c9531a98b7 100644 --- a/include/uapi/linux/nfsd_netlink.h +++ b/include/uapi/linux/nfsd_netlink.h @@ -290,6 +290,11 @@ enum { NFSD_A_CLIENT_LEASE_REMAINING, NFSD_A_CLIENT_RECLAIM_COMPLETE, NFSD_A_CLIENT_CALLBACK_STATE, + NFSD_A_CLIENT_SESSIONS, + NFSD_A_CLIENT_OPEN_STATEIDS, + NFSD_A_CLIENT_LOCK_STATEIDS, + NFSD_A_CLIENT_DELEGATION_STATEIDS, + NFSD_A_CLIENT_LAYOUT_STATEIDS, =20 __NFSD_A_CLIENT_MAX, NFSD_A_CLIENT_MAX =3D (__NFSD_A_CLIENT_MAX - 1) --=20 2.54.0