From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 69B4B381B08; Fri, 22 May 2026 12:29:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452952; cv=none; b=WbWIAa0ulw6XkX5Y6QOMnTvZIWHpAgdk3h5Xdx7y8ztlzZ+lBnvqUKYsJPym5JoPGJOYLTGL46wxBuVOA97Anw9Q/mN7clplPFezxkoQ5oKpguPOcCDKw21ujipgxW8oZHroFV+3mjTqbql+c0yeZYK7jkO8tIQBDviY51HtovY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452952; c=relaxed/simple; bh=ZKSdExH//yHPrO+bh/Uj+4YIl81jFCLLy6kU97jewL8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eSaStG4oN634r2pdYeNowX3N5EM4vfwbcxMQxwCf7iM5L9oAaLDpLfNPelTcnad6MjgvispBDC4q944A1hQW8CivLfz9MCBmyphHxbJjwe470r1FhCCVOq53BdrsUKzUcmH96i4W31D1Wrsj9/lWPCY2H9RFq/Y0APPvrRRdGO8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TeXvnBTy; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TeXvnBTy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 801EA1F00A3D; Fri, 22 May 2026 12:29:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452951; bh=tS3ewl/RblzPq0s0br2Ku7A8Mpy7aLrtToStoyvDFrA=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=TeXvnBTyL7iuOWL1a24Lnor9X4PSVyYyHfyxHwhqqIJ3p2phOwMA1/YNuU9NgA4a2 ChjmuL1d7jAhYAc+Lf2IbZNC97HiBONKf8fKHW5ZCxbK+yhvsohbI/OthP3dbP5esU ehLV+CpqnT3zjbKCsQ0r2e8NivyZe0+X9zIOCiJeTp8uZJrkmI5NwxCTM64SNvLkko rdgimQaznKCZg1cEeAfgHYHZylYCsVbzsuoI7QNYNZ8C8JOIcxflWPgQV4kihJ00H3 GoRdRWqpj5dnQ2GiBS3sHLZX4h8EvRrqdCJqcRORXs+2//G2zqczswVG7tRVIkTkGu 5NVcyPBlasPbA== From: Jeff Layton Date: Fri, 22 May 2026 08:28:50 -0400 Subject: [PATCH v4 01/21] nfsd: check fl_lmops in nfsd_breaker_owns_lease() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-1-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1106; i=jlayton@kernel.org; h=from:subject:message-id; bh=ZKSdExH//yHPrO+bh/Uj+4YIl81jFCLLy6kU97jewL8=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwMipJw1fKeK44+JEQe/XHs1jmU6NTMFXayM voy5E3b5hmJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMDAAKCRAADmhBGVaC FRx6D/4qhiAGbJOghjEaf/yFl33GPCMVkPQITfukTq0A+7eGld+61pHMwoISCt0xI4TBb+VJiAp +nv4W8CZ62c2Yy2WTkeqxg7u5EfXY1cjXYIJab9vEKwMGYsw3zS9k00Jn8Z7CmJwuyoNyy9Osdd sMKKIJFWtXC+tWWRJVK0hMUuLNjpZYDIFSNQa5OSQnR3q/CuTF0RtPJ4r0a9dCAVKsAy45v1WJ4 tgDv+gvDhnvPkKG0xcP83ooxbwp83x9SRRSUBQ8I8k8JlbktXkBK54AvTodA8UsVA4Br0pBsZcx aztG5JUTvwPmi8JWyWMt4KIy1+YNm9kc42DPo/uEVYmmB0zCiYhhrkeSuF+4knVykgSO6t4IP03 4f3ya1RG4phSvZxDT+DvFA6BrNoYWLDyE98knIXSSaDvG1RY6y3ACwSz1mYa6pbiyWfpTYJ5r2+ qLqLaoih2LQer/0uQn21CcgjX699dcmHDewLc6tJ6AqtI5vqX18sRfVAflpU1NVlcHtJ3q7xhSz NUPeiYyzYO/W+kShhTllUYxbxYr5eAWiAqIXwvC9nN46RLfk5cDDApgRkizDvWiMSEBJwwV2t5z DRp/N5MPpIsq0vvZxZZ9Aa2vufYTFMURLBumRXKsvgc8+fW8rGjCyLLoK1jC+7nULR4hRBzxAx/ QnT874ZhaaJBosQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Any lease created by nfsd will have its fl_lmops set to nfsd_lease_mng_ops. Do a quick check for that first when testing whether the lease breaker owns the lease. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2cf021b202a6..67e163ee13a2 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -91,6 +91,8 @@ static void _free_cpntf_state_locked(struct nfsd_net *nn,= struct nfs4_cpntf_stat static void nfsd4_file_hash_remove(struct nfs4_file *fi); static void deleg_reaper(struct nfsd_net *nn); =20 +static const struct lease_manager_operations nfsd_lease_mng_ops; + /* Locking: */ =20 enum nfsd4_st_mutex_lock_subclass { @@ -5663,6 +5665,10 @@ static bool nfsd_breaker_owns_lease(struct file_leas= e *fl) struct svc_rqst *rqst; struct nfs4_client *clp; =20 + /* Only nfsd leases */ + if (fl->fl_lmops !=3D &nfsd_lease_mng_ops) + return false; + rqst =3D nfsd_current_rqst(); if (!nfsd_v4client(rqst)) return false; --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 1C4803806AD; Fri, 22 May 2026 12:29:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452955; cv=none; b=qZhudYDE/JDt9jciwiK2ANWb1q2UTNg8HMdIrOOLuGfCYrNnxyYbGa3C9LFsL+pCh/+7Gcp3tNHHfz3MQsURMW5+nuB+hKj/9EFfgDPMSpBCoCvDrFySlXmUpUM6fDx+K2/+qBQ0uyN1S7s+w8oxZTR6muMpkaZod0vVKXd9wac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452955; c=relaxed/simple; bh=FRm/TvGa6QnyAkILHjmYgMZnO85GPEg6VGGCZqnV5fQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WJsvWv0JR+x6k3+1Hp1qWK8Qv/wV27kPM4gjgGHELXODfLuG9KCJDLXDh2M6c0TnX9G+um3eIrZ6v/NG0OS8YgB6DWxRMW5TAZZTqllGm/yG7yl/ffKKJu3J9DZuTg+emxrHswPSrvWVE/RkpyVNrR67WFD/4LI1v3xIGDSKPqg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WVSrYfTT; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="WVSrYfTT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3610B1F00A3F; Fri, 22 May 2026 12:29:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452952; bh=ILQxohJxsf3Mljx2/JAsrn32es/mAXwooX7eiKkh+FA=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=WVSrYfTTumdmwR2tw6nB4RK4Bu8uWw7sth2lcvpoMepCajk6aIoWVTOYCFarEa0uQ G+G8pz+kRi3iam38RqAim87m9mQTt2cweqVRnbBW4pz/gjSQgB8oiPHyB500wH6nQ+ DJ1CylMPMk9X+yJcqUg0XqM6Xmr8H80MYYmu2a9RGq9xnkZOE1Q2fpFfT+JO9u6IsE jUxrn/FXdc3Imd4HcDr0WyZxWUgpASIkTKW+z9SWYYK42lb8biGbnT7wga54yXqpd1 r3heMpGkrm2QENIUdUtSnzUGjevvnri6qPfOd0UNz/iZ/beUmnAxs9+BjrcoyC7Z7y xWQWWyZCTJdvA== From: Jeff Layton Date: Fri, 22 May 2026 08:28:51 -0400 Subject: [PATCH v4 02/21] nfsd: add protocol support for CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-2-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=49615; i=jlayton@kernel.org; h=from:subject:message-id; bh=FRm/TvGa6QnyAkILHjmYgMZnO85GPEg6VGGCZqnV5fQ=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwN6FSKmMLXSBnRt+HUlvzQ03mW6e2Yst4Qs 58qY4WHGQiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMDQAKCRAADmhBGVaC FX+GEACtxXuylYgDG2ikm/EJ/KXJItccLiyeTR/FG6oyenCRPEyju6rZ+RjemESrLKbchkXVOpm 9nqRK8z8aiFYQIFYV3fBOx7ysVEi0Q/MzKdDzJ0sPxNtUwAnkDKUqDmwWalwz50ho4v7ylJGj42 N3JQLs+5e4aKxgKdiyqpIRd5VoCisRKeHepfGLViqlOLD1IflwbbVCeW213qfZtM5ZdZKex0626 UwTp29KDz7s4H766GpF+3Alnb9gTBDU1AeOfioLi/FaCeY6eXicKb6wIJO0Sx518NXSFJewbSL7 2vQNSqj9oFsLdTiAOVrUpsb8gZKBGjoAf/v2JIwcbwIUsHJoEr0arsFAXW2DJl3nXg8WOlKOPKF 0+fx34KjcUD+Ish5e6qj4nABz4c8sLku0xtoxU221khfkNSHGk11g34RNTpFPngL39VTXFXvYrE CgxWzMmGOEXooQeX0evLtwzos/uJqveOGTHI24Lr6K25s2FEYJMxRyzdkURJuumKofu5kyG1j37 +yxqpRg5NYRB8dIxF+iBnHFx8qbRCCXNW5NqgHQAEx+Gus1IzQaHvIghU4dcdPeCejrIvXQXbMm b850XJSCMocwWiLJlqiz2BzYUuHUC8mXuq9dmUA0S/56snhdA1SifQvD+PNfRocPv7zohEpuiZz hg7HTDmVUjXVfhA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add the necessary bits to nfs4_1.x and remove the duplicate definitions from nfs4.h and the uapi nfs4 header. Regenerate the xdr files. Note that regenerating these files caused conflicts with the definitions of NFS4_VERIFIER_SIZE and NFS4_FHSIZE in include/uapi/linux/nfs4.h. These constants are defined by the RFC, and are not part of the kernel API. They have been removed. Userspace consumers who require those constants should plan to get them from more authoritative sources. Signed-off-by: Jeff Layton --- Documentation/sunrpc/xdr/nfs4_1.x | 250 ++++++++++++++- fs/nfsd/nfs4xdr_gen.c | 590 +++++++++++++++++++++++++++++++= +++- fs/nfsd/nfs4xdr_gen.h | 20 +- fs/nfsd/trace.h | 1 + include/linux/nfs4.h | 127 -------- include/linux/sunrpc/xdrgen/nfs4_1.h | 280 ++++++++++++++++- include/uapi/linux/nfs4.h | 2 - 7 files changed, 1129 insertions(+), 141 deletions(-) diff --git a/Documentation/sunrpc/xdr/nfs4_1.x b/Documentation/sunrpc/xdr/n= fs4_1.x index 5b45547b2ebc..632f5b579c39 100644 --- a/Documentation/sunrpc/xdr/nfs4_1.x +++ b/Documentation/sunrpc/xdr/nfs4_1.x @@ -45,19 +45,165 @@ pragma header nfs4; /* * Basic typedefs for RFC 1832 data type definitions */ -typedef hyper int64_t; -typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef hyper int64_t; +typedef unsigned hyper uint64_t; + +const NFS4_VERIFIER_SIZE =3D 8; +const NFS4_FHSIZE =3D 128; + +enum nfsstat4 { + NFS4_OK =3D 0, /* everything is okay */ + NFS4ERR_PERM =3D 1, /* caller not privileged */ + NFS4ERR_NOENT =3D 2, /* no such file/directory */ + NFS4ERR_IO =3D 5, /* hard I/O error */ + NFS4ERR_NXIO =3D 6, /* no such device */ + NFS4ERR_ACCESS =3D 13, /* access denied */ + NFS4ERR_EXIST =3D 17, /* file already exists */ + NFS4ERR_XDEV =3D 18, /* different filesystems */ + + /* + * Please do not allocate value 19; it was used in NFSv3 + * and we do not want a value in NFSv3 to have a different + * meaning in NFSv4.x. + */ + + NFS4ERR_NOTDIR =3D 20, /* should be a directory */ + NFS4ERR_ISDIR =3D 21, /* should not be directory */ + NFS4ERR_INVAL =3D 22, /* invalid argument */ + NFS4ERR_FBIG =3D 27, /* file exceeds server max */ + NFS4ERR_NOSPC =3D 28, /* no space on filesystem */ + NFS4ERR_ROFS =3D 30, /* read-only filesystem */ + NFS4ERR_MLINK =3D 31, /* too many hard links */ + NFS4ERR_NAMETOOLONG =3D 63, /* name exceeds server max */ + NFS4ERR_NOTEMPTY =3D 66, /* directory not empty */ + NFS4ERR_DQUOT =3D 69, /* hard quota limit reached*/ + NFS4ERR_STALE =3D 70, /* file no longer exists */ + NFS4ERR_BADHANDLE =3D 10001,/* Illegal filehandle */ + NFS4ERR_BAD_COOKIE =3D 10003,/* READDIR cookie is stale */ + NFS4ERR_NOTSUPP =3D 10004,/* operation not supported */ + NFS4ERR_TOOSMALL =3D 10005,/* response limit exceeded */ + NFS4ERR_SERVERFAULT =3D 10006,/* undefined server error */ + NFS4ERR_BADTYPE =3D 10007,/* type invalid for CREATE */ + NFS4ERR_DELAY =3D 10008,/* file "busy" - retry */ + NFS4ERR_SAME =3D 10009,/* nverify says attrs same */ + NFS4ERR_DENIED =3D 10010,/* lock unavailable */ + NFS4ERR_EXPIRED =3D 10011,/* lock lease expired */ + NFS4ERR_LOCKED =3D 10012,/* I/O failed due to lock */ + NFS4ERR_GRACE =3D 10013,/* in grace period */ + NFS4ERR_FHEXPIRED =3D 10014,/* filehandle expired */ + NFS4ERR_SHARE_DENIED =3D 10015,/* share reserve denied */ + NFS4ERR_WRONGSEC =3D 10016,/* wrong security flavor */ + NFS4ERR_CLID_INUSE =3D 10017,/* clientid in use */ + + /* NFS4ERR_RESOURCE is not a valid error in NFSv4.1 */ + NFS4ERR_RESOURCE =3D 10018,/* resource exhaustion */ + + NFS4ERR_MOVED =3D 10019,/* filesystem relocated */ + NFS4ERR_NOFILEHANDLE =3D 10020,/* current FH is not set */ + NFS4ERR_MINOR_VERS_MISMATCH=3D 10021,/* minor vers not supp */ + NFS4ERR_STALE_CLIENTID =3D 10022,/* server has rebooted */ + NFS4ERR_STALE_STATEID =3D 10023,/* server has rebooted */ + NFS4ERR_OLD_STATEID =3D 10024,/* state is out of sync */ + NFS4ERR_BAD_STATEID =3D 10025,/* incorrect stateid */ + NFS4ERR_BAD_SEQID =3D 10026,/* request is out of seq. */ + NFS4ERR_NOT_SAME =3D 10027,/* verify - attrs not same */ + NFS4ERR_LOCK_RANGE =3D 10028,/* overlapping lock range */ + NFS4ERR_SYMLINK =3D 10029,/* should be file/directory*/ + NFS4ERR_RESTOREFH =3D 10030,/* no saved filehandle */ + NFS4ERR_LEASE_MOVED =3D 10031,/* some filesystem moved */ + NFS4ERR_ATTRNOTSUPP =3D 10032,/* recommended attr not sup*/ + NFS4ERR_NO_GRACE =3D 10033,/* reclaim outside of grace*/ + NFS4ERR_RECLAIM_BAD =3D 10034,/* reclaim error at server */ + NFS4ERR_RECLAIM_CONFLICT=3D 10035,/* conflict on reclaim */ + NFS4ERR_BADXDR =3D 10036,/* XDR decode failed */ + NFS4ERR_LOCKS_HELD =3D 10037,/* file locks held at CLOSE*/ + NFS4ERR_OPENMODE =3D 10038,/* conflict in OPEN and I/O*/ + NFS4ERR_BADOWNER =3D 10039,/* owner translation bad */ + NFS4ERR_BADCHAR =3D 10040,/* utf-8 char not supported*/ + NFS4ERR_BADNAME =3D 10041,/* name not supported */ + NFS4ERR_BAD_RANGE =3D 10042,/* lock range not supported*/ + NFS4ERR_LOCK_NOTSUPP =3D 10043,/* no atomic up/downgrade */ + NFS4ERR_OP_ILLEGAL =3D 10044,/* undefined operation */ + NFS4ERR_DEADLOCK =3D 10045,/* file locking deadlock */ + NFS4ERR_FILE_OPEN =3D 10046,/* open file blocks op. */ + NFS4ERR_ADMIN_REVOKED =3D 10047,/* lockowner state revoked */ + NFS4ERR_CB_PATH_DOWN =3D 10048,/* callback path down */ + + /* NFSv4.1 errors start here. */ + + NFS4ERR_BADIOMODE =3D 10049, + NFS4ERR_BADLAYOUT =3D 10050, + NFS4ERR_BAD_SESSION_DIGEST =3D 10051, + NFS4ERR_BADSESSION =3D 10052, + NFS4ERR_BADSLOT =3D 10053, + NFS4ERR_COMPLETE_ALREADY =3D 10054, + NFS4ERR_CONN_NOT_BOUND_TO_SESSION =3D 10055, + NFS4ERR_DELEG_ALREADY_WANTED =3D 10056, + NFS4ERR_BACK_CHAN_BUSY =3D 10057,/*backchan reqs outstanding*/ + NFS4ERR_LAYOUTTRYLATER =3D 10058, + NFS4ERR_LAYOUTUNAVAILABLE =3D 10059, + NFS4ERR_NOMATCHING_LAYOUT =3D 10060, + NFS4ERR_RECALLCONFLICT =3D 10061, + NFS4ERR_UNKNOWN_LAYOUTTYPE =3D 10062, + NFS4ERR_SEQ_MISORDERED =3D 10063,/* unexpected seq.ID in req*/ + NFS4ERR_SEQUENCE_POS =3D 10064,/* [CB_]SEQ. op not 1st op */ + NFS4ERR_REQ_TOO_BIG =3D 10065,/* request too big */ + NFS4ERR_REP_TOO_BIG =3D 10066,/* reply too big */ + NFS4ERR_REP_TOO_BIG_TO_CACHE =3D10067,/* rep. not all cached*/ + NFS4ERR_RETRY_UNCACHED_REP =3D10068,/* retry & rep. uncached*/ + NFS4ERR_UNSAFE_COMPOUND =3D10069,/* retry/recovery too hard */ + NFS4ERR_TOO_MANY_OPS =3D 10070,/*too many ops in [CB_]COMP*/ + NFS4ERR_OP_NOT_IN_SESSION =3D10071,/* op needs [CB_]SEQ. op */ + NFS4ERR_HASH_ALG_UNSUPP =3D 10072, /* hash alg. not supp. */ + /* Error 10073 is unused. */ + NFS4ERR_CLIENTID_BUSY =3D 10074,/* clientid has state */ + NFS4ERR_PNFS_IO_HOLE =3D 10075,/* IO to _SPARSE file hole */ + NFS4ERR_SEQ_FALSE_RETRY=3D 10076,/* Retry !=3D original req. */ + NFS4ERR_BAD_HIGH_SLOT =3D 10077,/* req has bad highest_slot*/ + NFS4ERR_DEADSESSION =3D 10078,/*new req sent to dead sess*/ + NFS4ERR_ENCR_ALG_UNSUPP=3D 10079,/* encr alg. not supp. */ + NFS4ERR_PNFS_NO_LAYOUT =3D 10080,/* I/O without a layout */ + NFS4ERR_NOT_ONLY_OP =3D 10081,/* addl ops not allowed */ + NFS4ERR_WRONG_CRED =3D 10082,/* op done by wrong cred */ + NFS4ERR_WRONG_TYPE =3D 10083,/* op on wrong type object */ + NFS4ERR_DIRDELEG_UNAVAIL=3D10084,/* delegation not avail. */ + NFS4ERR_REJECT_DELEG =3D 10085,/* cb rejected delegation */ + NFS4ERR_RETURNCONFLICT =3D 10086,/* layout get before return*/ + NFS4ERR_DELEG_REVOKED =3D 10087, /* deleg./layout revoked */ + NFS4ERR_PARTNER_NOTSUPP =3D 10088, + NFS4ERR_PARTNER_NO_AUTH =3D 10089, + NFS4ERR_UNION_NOTSUPP =3D 10090, + NFS4ERR_OFFLOAD_DENIED =3D 10091, + NFS4ERR_WRONG_LFS =3D 10092, + NFS4ERR_BADLABEL =3D 10093, + NFS4ERR_OFFLOAD_NO_REQS =3D 10094, + NFS4ERR_NOXATTR =3D 10095, + NFS4ERR_XATTR2BIG =3D 10096, + + /* always set this to one more than the last one in the enum */ + NFS4ERR_FIRST_FREE =3D 10097 +}; =20 /* * Basic data types */ +typedef opaque attrlist4<>; typedef uint32_t bitmap4<>; +typedef opaque verifier4[NFS4_VERIFIER_SIZE]; +typedef uint64_t nfs_cookie4; +typedef opaque nfs_fh4; =20 typedef opaque utf8string<>; typedef utf8string utf8str_cis; typedef utf8string utf8str_cs; typedef utf8string utf8str_mixed; =20 +typedef utf8str_cs component4; +typedef utf8str_cs linktext4; +typedef component4 pathname4<>; + /* * Timeval */ @@ -66,6 +212,21 @@ struct nfstime4 { uint32_t nseconds; }; =20 +/* + * File attribute container + */ +struct fattr4 { + bitmap4 attrmask; + attrlist4 attr_vals; +}; + +/* + * Stateid + */ +struct stateid4 { + uint32_t seqid; + opaque other[12]; +}; =20 /* * The following content was extracted from draft-ietf-nfsv4-delstid @@ -245,3 +406,88 @@ const FATTR4_ACL_TRUEFORM =3D 89; const FATTR4_ACL_TRUEFORM_SCOPE =3D 90; const FATTR4_POSIX_DEFAULT_ACL =3D 91; const FATTR4_POSIX_ACCESS_ACL =3D 92; + +/* + * Directory notification types. + */ +enum notify_type4 { + NOTIFY4_CHANGE_CHILD_ATTRS =3D 0, + NOTIFY4_CHANGE_DIR_ATTRS =3D 1, + NOTIFY4_REMOVE_ENTRY =3D 2, + NOTIFY4_ADD_ENTRY =3D 3, + NOTIFY4_RENAME_ENTRY =3D 4, + NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5 +}; + +/* Changed entry information. */ +struct notify_entry4 { + component4 ne_file; + fattr4 ne_attrs; +}; + +/* Previous entry information */ +struct prev_entry4 { + notify_entry4 pe_prev_entry; + /* what READDIR returned for this entry */ + nfs_cookie4 pe_prev_entry_cookie; +}; + +struct notify_remove4 { + notify_entry4 nrm_old_entry; + nfs_cookie4 nrm_old_entry_cookie; +}; +pragma public notify_remove4; + +struct notify_add4 { + /* + * Information on object + * possibly renamed over. + */ + notify_remove4 nad_old_entry<1>; + notify_entry4 nad_new_entry; + /* what READDIR would have returned for this entry */ + nfs_cookie4 nad_new_entry_cookie<1>; + prev_entry4 nad_prev_entry<1>; + bool nad_last_entry; +}; +pragma public notify_add4; + +struct notify_attr4 { + notify_entry4 na_changed_entry; +}; +pragma public notify_attr4; + +struct notify_rename4 { + notify_remove4 nrn_old_entry; + notify_add4 nrn_new_entry; +}; +pragma public notify_rename4; + +struct notify_verifier4 { + verifier4 nv_old_cookieverf; + verifier4 nv_new_cookieverf; +}; + +/* + * Objects of type notify_<>4 and + * notify_device_<>4 are encoded in this. + */ +typedef opaque notifylist4<>; + +struct notify4 { + /* composed from notify_type4 or notify_deviceid_type4 */ + bitmap4 notify_mask; + notifylist4 notify_vals; +}; + +struct CB_NOTIFY4args { + stateid4 cna_stateid; + nfs_fh4 cna_fh; + notify4 cna_changes<>; +}; +pragma public CB_NOTIFY4args; + +struct CB_NOTIFY4res { + nfsstat4 cnr_status; +}; +pragma public CB_NOTIFY4res; diff --git a/fs/nfsd/nfs4xdr_gen.c b/fs/nfsd/nfs4xdr_gen.c index 824497051b87..5e656d6bbb8e 100644 --- a/fs/nfsd/nfs4xdr_gen.c +++ b/fs/nfsd/nfs4xdr_gen.c @@ -1,16 +1,16 @@ // SPDX-License-Identifier: GPL-2.0 // Generated by xdrgen. Manual edits will be lost. // XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x -// XDR specification modification time: Thu Jan 8 23:12:07 2026 +// XDR specification modification time: Wed Mar 25 11:39:22 2026 =20 #include =20 #include "nfs4xdr_gen.h" =20 static bool __maybe_unused -xdrgen_decode_int64_t(struct xdr_stream *xdr, int64_t *ptr) +xdrgen_decode_int32_t(struct xdr_stream *xdr, int32_t *ptr) { - return xdrgen_decode_hyper(xdr, ptr); + return xdrgen_decode_int(xdr, ptr); } =20 static bool __maybe_unused @@ -19,6 +19,155 @@ xdrgen_decode_uint32_t(struct xdr_stream *xdr, uint32_t= *ptr) return xdrgen_decode_unsigned_int(xdr, ptr); } =20 +static bool __maybe_unused +xdrgen_decode_int64_t(struct xdr_stream *xdr, int64_t *ptr) +{ + return xdrgen_decode_hyper(xdr, ptr); +} + +static bool __maybe_unused +xdrgen_decode_uint64_t(struct xdr_stream *xdr, uint64_t *ptr) +{ + return xdrgen_decode_unsigned_hyper(xdr, ptr); +} + +static bool __maybe_unused +xdrgen_decode_nfsstat4(struct xdr_stream *xdr, nfsstat4 *ptr) +{ + u32 val; + + if (xdr_stream_decode_u32(xdr, &val) < 0) + return false; + /* Compiler may optimize to a range check for dense enums */ + switch (val) { + case NFS4_OK: + case NFS4ERR_PERM: + case NFS4ERR_NOENT: + case NFS4ERR_IO: + case NFS4ERR_NXIO: + case NFS4ERR_ACCESS: + case NFS4ERR_EXIST: + case NFS4ERR_XDEV: + case NFS4ERR_NOTDIR: + case NFS4ERR_ISDIR: + case NFS4ERR_INVAL: + case NFS4ERR_FBIG: + case NFS4ERR_NOSPC: + case NFS4ERR_ROFS: + case NFS4ERR_MLINK: + case NFS4ERR_NAMETOOLONG: + case NFS4ERR_NOTEMPTY: + case NFS4ERR_DQUOT: + case NFS4ERR_STALE: + case NFS4ERR_BADHANDLE: + case NFS4ERR_BAD_COOKIE: + case NFS4ERR_NOTSUPP: + case NFS4ERR_TOOSMALL: + case NFS4ERR_SERVERFAULT: + case NFS4ERR_BADTYPE: + case NFS4ERR_DELAY: + case NFS4ERR_SAME: + case NFS4ERR_DENIED: + case NFS4ERR_EXPIRED: + case NFS4ERR_LOCKED: + case NFS4ERR_GRACE: + case NFS4ERR_FHEXPIRED: + case NFS4ERR_SHARE_DENIED: + case NFS4ERR_WRONGSEC: + case NFS4ERR_CLID_INUSE: + case NFS4ERR_RESOURCE: + case NFS4ERR_MOVED: + case NFS4ERR_NOFILEHANDLE: + case NFS4ERR_MINOR_VERS_MISMATCH: + case NFS4ERR_STALE_CLIENTID: + case NFS4ERR_STALE_STATEID: + case NFS4ERR_OLD_STATEID: + case NFS4ERR_BAD_STATEID: + case NFS4ERR_BAD_SEQID: + case NFS4ERR_NOT_SAME: + case NFS4ERR_LOCK_RANGE: + case NFS4ERR_SYMLINK: + case NFS4ERR_RESTOREFH: + case NFS4ERR_LEASE_MOVED: + case NFS4ERR_ATTRNOTSUPP: + case NFS4ERR_NO_GRACE: + case NFS4ERR_RECLAIM_BAD: + case NFS4ERR_RECLAIM_CONFLICT: + case NFS4ERR_BADXDR: + case NFS4ERR_LOCKS_HELD: + case NFS4ERR_OPENMODE: + case NFS4ERR_BADOWNER: + case NFS4ERR_BADCHAR: + case NFS4ERR_BADNAME: + case NFS4ERR_BAD_RANGE: + case NFS4ERR_LOCK_NOTSUPP: + case NFS4ERR_OP_ILLEGAL: + case NFS4ERR_DEADLOCK: + case NFS4ERR_FILE_OPEN: + case NFS4ERR_ADMIN_REVOKED: + case NFS4ERR_CB_PATH_DOWN: + case NFS4ERR_BADIOMODE: + case NFS4ERR_BADLAYOUT: + case NFS4ERR_BAD_SESSION_DIGEST: + case NFS4ERR_BADSESSION: + case NFS4ERR_BADSLOT: + case NFS4ERR_COMPLETE_ALREADY: + case NFS4ERR_CONN_NOT_BOUND_TO_SESSION: + case NFS4ERR_DELEG_ALREADY_WANTED: + case NFS4ERR_BACK_CHAN_BUSY: + case NFS4ERR_LAYOUTTRYLATER: + case NFS4ERR_LAYOUTUNAVAILABLE: + case NFS4ERR_NOMATCHING_LAYOUT: + case NFS4ERR_RECALLCONFLICT: + case NFS4ERR_UNKNOWN_LAYOUTTYPE: + case NFS4ERR_SEQ_MISORDERED: + case NFS4ERR_SEQUENCE_POS: + case NFS4ERR_REQ_TOO_BIG: + case NFS4ERR_REP_TOO_BIG: + case NFS4ERR_REP_TOO_BIG_TO_CACHE: + case NFS4ERR_RETRY_UNCACHED_REP: + case NFS4ERR_UNSAFE_COMPOUND: + case NFS4ERR_TOO_MANY_OPS: + case NFS4ERR_OP_NOT_IN_SESSION: + case NFS4ERR_HASH_ALG_UNSUPP: + case NFS4ERR_CLIENTID_BUSY: + case NFS4ERR_PNFS_IO_HOLE: + case NFS4ERR_SEQ_FALSE_RETRY: + case NFS4ERR_BAD_HIGH_SLOT: + case NFS4ERR_DEADSESSION: + case NFS4ERR_ENCR_ALG_UNSUPP: + case NFS4ERR_PNFS_NO_LAYOUT: + case NFS4ERR_NOT_ONLY_OP: + case NFS4ERR_WRONG_CRED: + case NFS4ERR_WRONG_TYPE: + case NFS4ERR_DIRDELEG_UNAVAIL: + case NFS4ERR_REJECT_DELEG: + case NFS4ERR_RETURNCONFLICT: + case NFS4ERR_DELEG_REVOKED: + case NFS4ERR_PARTNER_NOTSUPP: + case NFS4ERR_PARTNER_NO_AUTH: + case NFS4ERR_UNION_NOTSUPP: + case NFS4ERR_OFFLOAD_DENIED: + case NFS4ERR_WRONG_LFS: + case NFS4ERR_BADLABEL: + case NFS4ERR_OFFLOAD_NO_REQS: + case NFS4ERR_NOXATTR: + case NFS4ERR_XATTR2BIG: + case NFS4ERR_FIRST_FREE: + break; + default: + return false; + } + *ptr =3D val; + return true; +} + +static bool __maybe_unused +xdrgen_decode_attrlist4(struct xdr_stream *xdr, attrlist4 *ptr) +{ + return xdrgen_decode_opaque(xdr, ptr, 0); +} + static bool __maybe_unused xdrgen_decode_bitmap4(struct xdr_stream *xdr, bitmap4 *ptr) { @@ -30,6 +179,24 @@ xdrgen_decode_bitmap4(struct xdr_stream *xdr, bitmap4 *= ptr) return true; } =20 +static bool __maybe_unused +xdrgen_decode_verifier4(struct xdr_stream *xdr, verifier4 *ptr) +{ + return xdr_stream_decode_opaque_fixed(xdr, ptr, NFS4_VERIFIER_SIZE) =3D= =3D 0; +} + +static bool __maybe_unused +xdrgen_decode_nfs_cookie4(struct xdr_stream *xdr, nfs_cookie4 *ptr) +{ + return xdrgen_decode_uint64_t(xdr, ptr); +} + +static bool __maybe_unused +xdrgen_decode_nfs_fh4(struct xdr_stream *xdr, nfs_fh4 *ptr) +{ + return xdrgen_decode_opaque(xdr, ptr, NFS4_FHSIZE); +} + static bool __maybe_unused xdrgen_decode_utf8string(struct xdr_stream *xdr, utf8string *ptr) { @@ -54,6 +221,29 @@ xdrgen_decode_utf8str_mixed(struct xdr_stream *xdr, utf= 8str_mixed *ptr) return xdrgen_decode_utf8string(xdr, ptr); } =20 +static bool __maybe_unused +xdrgen_decode_component4(struct xdr_stream *xdr, component4 *ptr) +{ + return xdrgen_decode_utf8str_cs(xdr, ptr); +} + +static bool __maybe_unused +xdrgen_decode_linktext4(struct xdr_stream *xdr, linktext4 *ptr) +{ + return xdrgen_decode_utf8str_cs(xdr, ptr); +} + +static bool __maybe_unused +xdrgen_decode_pathname4(struct xdr_stream *xdr, pathname4 *ptr) +{ + if (xdr_stream_decode_u32(xdr, &ptr->count) < 0) + return false; + for (u32 i =3D 0; i < ptr->count; i++) + if (!xdrgen_decode_component4(xdr, &ptr->element[i])) + return false; + return true; +} + static bool __maybe_unused xdrgen_decode_nfstime4(struct xdr_stream *xdr, struct nfstime4 *ptr) { @@ -64,6 +254,26 @@ xdrgen_decode_nfstime4(struct xdr_stream *xdr, struct n= fstime4 *ptr) return true; } =20 +static bool __maybe_unused +xdrgen_decode_fattr4(struct xdr_stream *xdr, struct fattr4 *ptr) +{ + if (!xdrgen_decode_bitmap4(xdr, &ptr->attrmask)) + return false; + if (!xdrgen_decode_attrlist4(xdr, &ptr->attr_vals)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_decode_stateid4(struct xdr_stream *xdr, struct stateid4 *ptr) +{ + if (!xdrgen_decode_uint32_t(xdr, &ptr->seqid)) + return false; + if (xdr_stream_decode_opaque_fixed(xdr, ptr->other, 12) < 0) + return false; + return true; +} + static bool __maybe_unused xdrgen_decode_fattr4_offline(struct xdr_stream *xdr, fattr4_offline *ptr) { @@ -366,9 +576,160 @@ xdrgen_decode_fattr4_posix_access_acl(struct xdr_stre= am *xdr, fattr4_posix_acces */ =20 static bool __maybe_unused -xdrgen_encode_int64_t(struct xdr_stream *xdr, const int64_t value) +xdrgen_decode_notify_type4(struct xdr_stream *xdr, notify_type4 *ptr) { - return xdrgen_encode_hyper(xdr, value); + u32 val; + + if (xdr_stream_decode_u32(xdr, &val) < 0) + return false; + /* Compiler may optimize to a range check for dense enums */ + switch (val) { + case NOTIFY4_CHANGE_CHILD_ATTRS: + case NOTIFY4_CHANGE_DIR_ATTRS: + case NOTIFY4_REMOVE_ENTRY: + case NOTIFY4_ADD_ENTRY: + case NOTIFY4_RENAME_ENTRY: + case NOTIFY4_CHANGE_COOKIE_VERIFIER: + break; + default: + return false; + } + *ptr =3D val; + return true; +} + +static bool __maybe_unused +xdrgen_decode_notify_entry4(struct xdr_stream *xdr, struct notify_entry4 *= ptr) +{ + if (!xdrgen_decode_component4(xdr, &ptr->ne_file)) + return false; + if (!xdrgen_decode_fattr4(xdr, &ptr->ne_attrs)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_decode_prev_entry4(struct xdr_stream *xdr, struct prev_entry4 *ptr) +{ + if (!xdrgen_decode_notify_entry4(xdr, &ptr->pe_prev_entry)) + return false; + if (!xdrgen_decode_nfs_cookie4(xdr, &ptr->pe_prev_entry_cookie)) + return false; + return true; +} + +bool +xdrgen_decode_notify_remove4(struct xdr_stream *xdr, struct notify_remove4= *ptr) +{ + if (!xdrgen_decode_notify_entry4(xdr, &ptr->nrm_old_entry)) + return false; + if (!xdrgen_decode_nfs_cookie4(xdr, &ptr->nrm_old_entry_cookie)) + return false; + return true; +} + +bool +xdrgen_decode_notify_add4(struct xdr_stream *xdr, struct notify_add4 *ptr) +{ + if (xdr_stream_decode_u32(xdr, &ptr->nad_old_entry.count) < 0) + return false; + if (ptr->nad_old_entry.count > 1) + return false; + for (u32 i =3D 0; i < ptr->nad_old_entry.count; i++) + if (!xdrgen_decode_notify_remove4(xdr, &ptr->nad_old_entry.element[i])) + return false; + if (!xdrgen_decode_notify_entry4(xdr, &ptr->nad_new_entry)) + return false; + if (xdr_stream_decode_u32(xdr, &ptr->nad_new_entry_cookie.count) < 0) + return false; + if (ptr->nad_new_entry_cookie.count > 1) + return false; + for (u32 i =3D 0; i < ptr->nad_new_entry_cookie.count; i++) + if (!xdrgen_decode_nfs_cookie4(xdr, &ptr->nad_new_entry_cookie.element[i= ])) + return false; + if (xdr_stream_decode_u32(xdr, &ptr->nad_prev_entry.count) < 0) + return false; + if (ptr->nad_prev_entry.count > 1) + return false; + for (u32 i =3D 0; i < ptr->nad_prev_entry.count; i++) + if (!xdrgen_decode_prev_entry4(xdr, &ptr->nad_prev_entry.element[i])) + return false; + if (!xdrgen_decode_bool(xdr, &ptr->nad_last_entry)) + return false; + return true; +} + +bool +xdrgen_decode_notify_attr4(struct xdr_stream *xdr, struct notify_attr4 *pt= r) +{ + if (!xdrgen_decode_notify_entry4(xdr, &ptr->na_changed_entry)) + return false; + return true; +} + +bool +xdrgen_decode_notify_rename4(struct xdr_stream *xdr, struct notify_rename4= *ptr) +{ + if (!xdrgen_decode_notify_remove4(xdr, &ptr->nrn_old_entry)) + return false; + if (!xdrgen_decode_notify_add4(xdr, &ptr->nrn_new_entry)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_decode_notify_verifier4(struct xdr_stream *xdr, struct notify_verif= ier4 *ptr) +{ + if (!xdrgen_decode_verifier4(xdr, &ptr->nv_old_cookieverf)) + return false; + if (!xdrgen_decode_verifier4(xdr, &ptr->nv_new_cookieverf)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_decode_notifylist4(struct xdr_stream *xdr, notifylist4 *ptr) +{ + return xdrgen_decode_opaque(xdr, ptr, 0); +} + +static bool __maybe_unused +xdrgen_decode_notify4(struct xdr_stream *xdr, struct notify4 *ptr) +{ + if (!xdrgen_decode_bitmap4(xdr, &ptr->notify_mask)) + return false; + if (!xdrgen_decode_notifylist4(xdr, &ptr->notify_vals)) + return false; + return true; +} + +bool +xdrgen_decode_CB_NOTIFY4args(struct xdr_stream *xdr, struct CB_NOTIFY4args= *ptr) +{ + if (!xdrgen_decode_stateid4(xdr, &ptr->cna_stateid)) + return false; + if (!xdrgen_decode_nfs_fh4(xdr, &ptr->cna_fh)) + return false; + if (xdr_stream_decode_u32(xdr, &ptr->cna_changes.count) < 0) + return false; + for (u32 i =3D 0; i < ptr->cna_changes.count; i++) + if (!xdrgen_decode_notify4(xdr, &ptr->cna_changes.element[i])) + return false; + return true; +} + +bool +xdrgen_decode_CB_NOTIFY4res(struct xdr_stream *xdr, struct CB_NOTIFY4res *= ptr) +{ + if (!xdrgen_decode_nfsstat4(xdr, &ptr->cnr_status)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_encode_int32_t(struct xdr_stream *xdr, const int32_t value) +{ + return xdrgen_encode_int(xdr, value); } =20 static bool __maybe_unused @@ -377,6 +738,30 @@ xdrgen_encode_uint32_t(struct xdr_stream *xdr, const u= int32_t value) return xdrgen_encode_unsigned_int(xdr, value); } =20 +static bool __maybe_unused +xdrgen_encode_int64_t(struct xdr_stream *xdr, const int64_t value) +{ + return xdrgen_encode_hyper(xdr, value); +} + +static bool __maybe_unused +xdrgen_encode_uint64_t(struct xdr_stream *xdr, const uint64_t value) +{ + return xdrgen_encode_unsigned_hyper(xdr, value); +} + +static bool __maybe_unused +xdrgen_encode_nfsstat4(struct xdr_stream *xdr, nfsstat4 value) +{ + return xdr_stream_encode_u32(xdr, value) =3D=3D XDR_UNIT; +} + +static bool __maybe_unused +xdrgen_encode_attrlist4(struct xdr_stream *xdr, const attrlist4 value) +{ + return xdr_stream_encode_opaque(xdr, value.data, value.len) >=3D 0; +} + static bool __maybe_unused xdrgen_encode_bitmap4(struct xdr_stream *xdr, const bitmap4 value) { @@ -388,6 +773,24 @@ xdrgen_encode_bitmap4(struct xdr_stream *xdr, const bi= tmap4 value) return true; } =20 +static bool __maybe_unused +xdrgen_encode_verifier4(struct xdr_stream *xdr, const verifier4 value) +{ + return xdr_stream_encode_opaque_fixed(xdr, value, NFS4_VERIFIER_SIZE) >= =3D 0; +} + +static bool __maybe_unused +xdrgen_encode_nfs_cookie4(struct xdr_stream *xdr, const nfs_cookie4 value) +{ + return xdrgen_encode_uint64_t(xdr, value); +} + +static bool __maybe_unused +xdrgen_encode_nfs_fh4(struct xdr_stream *xdr, const nfs_fh4 value) +{ + return xdr_stream_encode_opaque(xdr, value.data, value.len) >=3D 0; +} + static bool __maybe_unused xdrgen_encode_utf8string(struct xdr_stream *xdr, const utf8string value) { @@ -412,6 +815,29 @@ xdrgen_encode_utf8str_mixed(struct xdr_stream *xdr, co= nst utf8str_mixed value) return xdrgen_encode_utf8string(xdr, value); } =20 +static bool __maybe_unused +xdrgen_encode_component4(struct xdr_stream *xdr, const component4 value) +{ + return xdrgen_encode_utf8str_cs(xdr, value); +} + +static bool __maybe_unused +xdrgen_encode_linktext4(struct xdr_stream *xdr, const linktext4 value) +{ + return xdrgen_encode_utf8str_cs(xdr, value); +} + +static bool __maybe_unused +xdrgen_encode_pathname4(struct xdr_stream *xdr, const pathname4 value) +{ + if (xdr_stream_encode_u32(xdr, value.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value.count; i++) + if (!xdrgen_encode_component4(xdr, value.element[i])) + return false; + return true; +} + static bool __maybe_unused xdrgen_encode_nfstime4(struct xdr_stream *xdr, const struct nfstime4 *valu= e) { @@ -422,6 +848,26 @@ xdrgen_encode_nfstime4(struct xdr_stream *xdr, const s= truct nfstime4 *value) return true; } =20 +static bool __maybe_unused +xdrgen_encode_fattr4(struct xdr_stream *xdr, const struct fattr4 *value) +{ + if (!xdrgen_encode_bitmap4(xdr, value->attrmask)) + return false; + if (!xdrgen_encode_attrlist4(xdr, value->attr_vals)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_encode_stateid4(struct xdr_stream *xdr, const struct stateid4 *valu= e) +{ + if (!xdrgen_encode_uint32_t(xdr, value->seqid)) + return false; + if (xdr_stream_encode_opaque_fixed(xdr, value->other, 12) < 0) + return false; + return true; +} + static bool __maybe_unused xdrgen_encode_fattr4_offline(struct xdr_stream *xdr, const fattr4_offline = value) { @@ -567,3 +1013,137 @@ xdrgen_encode_fattr4_posix_access_acl(struct xdr_str= eam *xdr, const fattr4_posix return false; return true; } + +static bool __maybe_unused +xdrgen_encode_notify_type4(struct xdr_stream *xdr, notify_type4 value) +{ + return xdr_stream_encode_u32(xdr, value) =3D=3D XDR_UNIT; +} + +static bool __maybe_unused +xdrgen_encode_notify_entry4(struct xdr_stream *xdr, const struct notify_en= try4 *value) +{ + if (!xdrgen_encode_component4(xdr, value->ne_file)) + return false; + if (!xdrgen_encode_fattr4(xdr, &value->ne_attrs)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_encode_prev_entry4(struct xdr_stream *xdr, const struct prev_entry4= *value) +{ + if (!xdrgen_encode_notify_entry4(xdr, &value->pe_prev_entry)) + return false; + if (!xdrgen_encode_nfs_cookie4(xdr, value->pe_prev_entry_cookie)) + return false; + return true; +} + +bool +xdrgen_encode_notify_remove4(struct xdr_stream *xdr, const struct notify_r= emove4 *value) +{ + if (!xdrgen_encode_notify_entry4(xdr, &value->nrm_old_entry)) + return false; + if (!xdrgen_encode_nfs_cookie4(xdr, value->nrm_old_entry_cookie)) + return false; + return true; +} + +bool +xdrgen_encode_notify_add4(struct xdr_stream *xdr, const struct notify_add4= *value) +{ + if (value->nad_old_entry.count > 1) + return false; + if (xdr_stream_encode_u32(xdr, value->nad_old_entry.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value->nad_old_entry.count; i++) + if (!xdrgen_encode_notify_remove4(xdr, &value->nad_old_entry.element[i])) + return false; + if (!xdrgen_encode_notify_entry4(xdr, &value->nad_new_entry)) + return false; + if (value->nad_new_entry_cookie.count > 1) + return false; + if (xdr_stream_encode_u32(xdr, value->nad_new_entry_cookie.count) !=3D XD= R_UNIT) + return false; + for (u32 i =3D 0; i < value->nad_new_entry_cookie.count; i++) + if (!xdrgen_encode_nfs_cookie4(xdr, value->nad_new_entry_cookie.element[= i])) + return false; + if (value->nad_prev_entry.count > 1) + return false; + if (xdr_stream_encode_u32(xdr, value->nad_prev_entry.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value->nad_prev_entry.count; i++) + if (!xdrgen_encode_prev_entry4(xdr, &value->nad_prev_entry.element[i])) + return false; + if (!xdrgen_encode_bool(xdr, value->nad_last_entry)) + return false; + return true; +} + +bool +xdrgen_encode_notify_attr4(struct xdr_stream *xdr, const struct notify_att= r4 *value) +{ + if (!xdrgen_encode_notify_entry4(xdr, &value->na_changed_entry)) + return false; + return true; +} + +bool +xdrgen_encode_notify_rename4(struct xdr_stream *xdr, const struct notify_r= ename4 *value) +{ + if (!xdrgen_encode_notify_remove4(xdr, &value->nrn_old_entry)) + return false; + if (!xdrgen_encode_notify_add4(xdr, &value->nrn_new_entry)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_encode_notify_verifier4(struct xdr_stream *xdr, const struct notify= _verifier4 *value) +{ + if (!xdrgen_encode_verifier4(xdr, value->nv_old_cookieverf)) + return false; + if (!xdrgen_encode_verifier4(xdr, value->nv_new_cookieverf)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_encode_notifylist4(struct xdr_stream *xdr, const notifylist4 value) +{ + return xdr_stream_encode_opaque(xdr, value.data, value.len) >=3D 0; +} + +static bool __maybe_unused +xdrgen_encode_notify4(struct xdr_stream *xdr, const struct notify4 *value) +{ + if (!xdrgen_encode_bitmap4(xdr, value->notify_mask)) + return false; + if (!xdrgen_encode_notifylist4(xdr, value->notify_vals)) + return false; + return true; +} + +bool +xdrgen_encode_CB_NOTIFY4args(struct xdr_stream *xdr, const struct CB_NOTIF= Y4args *value) +{ + if (!xdrgen_encode_stateid4(xdr, &value->cna_stateid)) + return false; + if (!xdrgen_encode_nfs_fh4(xdr, value->cna_fh)) + return false; + if (xdr_stream_encode_u32(xdr, value->cna_changes.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value->cna_changes.count; i++) + if (!xdrgen_encode_notify4(xdr, &value->cna_changes.element[i])) + return false; + return true; +} + +bool +xdrgen_encode_CB_NOTIFY4res(struct xdr_stream *xdr, const struct CB_NOTIFY= 4res *value) +{ + if (!xdrgen_encode_nfsstat4(xdr, value->cnr_status)) + return false; + return true; +} diff --git a/fs/nfsd/nfs4xdr_gen.h b/fs/nfsd/nfs4xdr_gen.h index 1c487f1a11ab..503fe2ccba51 100644 --- a/fs/nfsd/nfs4xdr_gen.h +++ b/fs/nfsd/nfs4xdr_gen.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */ -/* XDR specification modification time: Thu Jan 8 23:12:07 2026 */ +/* XDR specification modification time: Wed Mar 25 11:39:22 2026 */ =20 #ifndef _LINUX_XDRGEN_NFS4_1_DECL_H #define _LINUX_XDRGEN_NFS4_1_DECL_H @@ -32,4 +32,22 @@ bool xdrgen_decode_posixaceperm4(struct xdr_stream *xdr,= posixaceperm4 *ptr); bool xdrgen_encode_posixaceperm4(struct xdr_stream *xdr, const posixaceper= m4 value); =20 =20 +bool xdrgen_decode_notify_remove4(struct xdr_stream *xdr, struct notify_re= move4 *ptr); +bool xdrgen_encode_notify_remove4(struct xdr_stream *xdr, const struct not= ify_remove4 *value); + +bool xdrgen_decode_notify_add4(struct xdr_stream *xdr, struct notify_add4 = *ptr); +bool xdrgen_encode_notify_add4(struct xdr_stream *xdr, const struct notify= _add4 *value); + +bool xdrgen_decode_notify_attr4(struct xdr_stream *xdr, struct notify_attr= 4 *ptr); +bool xdrgen_encode_notify_attr4(struct xdr_stream *xdr, const struct notif= y_attr4 *value); + +bool xdrgen_decode_notify_rename4(struct xdr_stream *xdr, struct notify_re= name4 *ptr); +bool xdrgen_encode_notify_rename4(struct xdr_stream *xdr, const struct not= ify_rename4 *value); + +bool xdrgen_decode_CB_NOTIFY4args(struct xdr_stream *xdr, struct CB_NOTIFY= 4args *ptr); +bool xdrgen_encode_CB_NOTIFY4args(struct xdr_stream *xdr, const struct CB_= NOTIFY4args *value); + +bool xdrgen_decode_CB_NOTIFY4res(struct xdr_stream *xdr, struct CB_NOTIFY4= res *ptr); +bool xdrgen_encode_CB_NOTIFY4res(struct xdr_stream *xdr, const struct CB_N= OTIFY4res *value); + #endif /* _LINUX_XDRGEN_NFS4_1_DECL_H */ diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index 1c5a1e50f946..ebf5677c4e73 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -1677,6 +1677,7 @@ TRACE_EVENT(nfsd_cb_setup_err, { OP_CB_RECALL, "CB_RECALL" }, \ { OP_CB_LAYOUTRECALL, "CB_LAYOUTRECALL" }, \ { OP_CB_RECALL_ANY, "CB_RECALL_ANY" }, \ + { OP_CB_NOTIFY, "CB_NOTIFY" }, \ { OP_CB_NOTIFY_LOCK, "CB_NOTIFY_LOCK" }, \ { OP_CB_OFFLOAD, "CB_OFFLOAD" }) =20 diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index d87be1f25273..44e5e9fa12e1 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -171,133 +171,6 @@ Needs to be updated if more operations are defined in= future.*/ #define LAST_NFS42_OP OP_REMOVEXATTR #define LAST_NFS4_OP LAST_NFS42_OP =20 -enum nfsstat4 { - NFS4_OK =3D 0, - NFS4ERR_PERM =3D 1, - NFS4ERR_NOENT =3D 2, - NFS4ERR_IO =3D 5, - NFS4ERR_NXIO =3D 6, - NFS4ERR_ACCESS =3D 13, - NFS4ERR_EXIST =3D 17, - NFS4ERR_XDEV =3D 18, - /* Unused/reserved 19 */ - NFS4ERR_NOTDIR =3D 20, - NFS4ERR_ISDIR =3D 21, - NFS4ERR_INVAL =3D 22, - NFS4ERR_FBIG =3D 27, - NFS4ERR_NOSPC =3D 28, - NFS4ERR_ROFS =3D 30, - NFS4ERR_MLINK =3D 31, - NFS4ERR_NAMETOOLONG =3D 63, - NFS4ERR_NOTEMPTY =3D 66, - NFS4ERR_DQUOT =3D 69, - NFS4ERR_STALE =3D 70, - NFS4ERR_BADHANDLE =3D 10001, - NFS4ERR_BAD_COOKIE =3D 10003, - NFS4ERR_NOTSUPP =3D 10004, - NFS4ERR_TOOSMALL =3D 10005, - NFS4ERR_SERVERFAULT =3D 10006, - NFS4ERR_BADTYPE =3D 10007, - NFS4ERR_DELAY =3D 10008, - NFS4ERR_SAME =3D 10009, - NFS4ERR_DENIED =3D 10010, - NFS4ERR_EXPIRED =3D 10011, - NFS4ERR_LOCKED =3D 10012, - NFS4ERR_GRACE =3D 10013, - NFS4ERR_FHEXPIRED =3D 10014, - NFS4ERR_SHARE_DENIED =3D 10015, - NFS4ERR_WRONGSEC =3D 10016, - NFS4ERR_CLID_INUSE =3D 10017, - NFS4ERR_RESOURCE =3D 10018, - NFS4ERR_MOVED =3D 10019, - NFS4ERR_NOFILEHANDLE =3D 10020, - NFS4ERR_MINOR_VERS_MISMATCH =3D 10021, - NFS4ERR_STALE_CLIENTID =3D 10022, - NFS4ERR_STALE_STATEID =3D 10023, - NFS4ERR_OLD_STATEID =3D 10024, - NFS4ERR_BAD_STATEID =3D 10025, - NFS4ERR_BAD_SEQID =3D 10026, - NFS4ERR_NOT_SAME =3D 10027, - NFS4ERR_LOCK_RANGE =3D 10028, - NFS4ERR_SYMLINK =3D 10029, - NFS4ERR_RESTOREFH =3D 10030, - NFS4ERR_LEASE_MOVED =3D 10031, - NFS4ERR_ATTRNOTSUPP =3D 10032, - NFS4ERR_NO_GRACE =3D 10033, - NFS4ERR_RECLAIM_BAD =3D 10034, - NFS4ERR_RECLAIM_CONFLICT =3D 10035, - NFS4ERR_BADXDR =3D 10036, - NFS4ERR_LOCKS_HELD =3D 10037, - NFS4ERR_OPENMODE =3D 10038, - NFS4ERR_BADOWNER =3D 10039, - NFS4ERR_BADCHAR =3D 10040, - NFS4ERR_BADNAME =3D 10041, - NFS4ERR_BAD_RANGE =3D 10042, - NFS4ERR_LOCK_NOTSUPP =3D 10043, - NFS4ERR_OP_ILLEGAL =3D 10044, - NFS4ERR_DEADLOCK =3D 10045, - NFS4ERR_FILE_OPEN =3D 10046, - NFS4ERR_ADMIN_REVOKED =3D 10047, - NFS4ERR_CB_PATH_DOWN =3D 10048, - - /* nfs41 */ - NFS4ERR_BADIOMODE =3D 10049, - NFS4ERR_BADLAYOUT =3D 10050, - NFS4ERR_BAD_SESSION_DIGEST =3D 10051, - NFS4ERR_BADSESSION =3D 10052, - NFS4ERR_BADSLOT =3D 10053, - NFS4ERR_COMPLETE_ALREADY =3D 10054, - NFS4ERR_CONN_NOT_BOUND_TO_SESSION =3D 10055, - NFS4ERR_DELEG_ALREADY_WANTED =3D 10056, - NFS4ERR_BACK_CHAN_BUSY =3D 10057, /* backchan reqs outstanding */ - NFS4ERR_LAYOUTTRYLATER =3D 10058, - NFS4ERR_LAYOUTUNAVAILABLE =3D 10059, - NFS4ERR_NOMATCHING_LAYOUT =3D 10060, - NFS4ERR_RECALLCONFLICT =3D 10061, - NFS4ERR_UNKNOWN_LAYOUTTYPE =3D 10062, - NFS4ERR_SEQ_MISORDERED =3D 10063, /* unexpected seq.id in req */ - NFS4ERR_SEQUENCE_POS =3D 10064, /* [CB_]SEQ. op not 1st op */ - NFS4ERR_REQ_TOO_BIG =3D 10065, /* request too big */ - NFS4ERR_REP_TOO_BIG =3D 10066, /* reply too big */ - NFS4ERR_REP_TOO_BIG_TO_CACHE =3D 10067, /* rep. not all cached */ - NFS4ERR_RETRY_UNCACHED_REP =3D 10068, /* retry & rep. uncached */ - NFS4ERR_UNSAFE_COMPOUND =3D 10069, /* retry/recovery too hard */ - NFS4ERR_TOO_MANY_OPS =3D 10070, /* too many ops in [CB_]COMP */ - NFS4ERR_OP_NOT_IN_SESSION =3D 10071, /* op needs [CB_]SEQ. op */ - NFS4ERR_HASH_ALG_UNSUPP =3D 10072, /* hash alg. not supp. */ - /* Error 10073 is unused. */ - NFS4ERR_CLIENTID_BUSY =3D 10074, /* clientid has state */ - NFS4ERR_PNFS_IO_HOLE =3D 10075, /* IO to _SPARSE file hole */ - NFS4ERR_SEQ_FALSE_RETRY =3D 10076, /* retry not original */ - NFS4ERR_BAD_HIGH_SLOT =3D 10077, /* sequence arg bad */ - NFS4ERR_DEADSESSION =3D 10078, /* persistent session dead */ - NFS4ERR_ENCR_ALG_UNSUPP =3D 10079, /* SSV alg mismatch */ - NFS4ERR_PNFS_NO_LAYOUT =3D 10080, /* direct I/O with no layout */ - NFS4ERR_NOT_ONLY_OP =3D 10081, /* bad compound */ - NFS4ERR_WRONG_CRED =3D 10082, /* permissions:state change */ - NFS4ERR_WRONG_TYPE =3D 10083, /* current operation mismatch */ - NFS4ERR_DIRDELEG_UNAVAIL =3D 10084, /* no directory delegation */ - NFS4ERR_REJECT_DELEG =3D 10085, /* on callback */ - NFS4ERR_RETURNCONFLICT =3D 10086, /* outstanding layoutreturn */ - NFS4ERR_DELEG_REVOKED =3D 10087, /* deleg./layout revoked */ - - /* nfs42 */ - NFS4ERR_PARTNER_NOTSUPP =3D 10088, - NFS4ERR_PARTNER_NO_AUTH =3D 10089, - NFS4ERR_UNION_NOTSUPP =3D 10090, - NFS4ERR_OFFLOAD_DENIED =3D 10091, - NFS4ERR_WRONG_LFS =3D 10092, - NFS4ERR_BADLABEL =3D 10093, - NFS4ERR_OFFLOAD_NO_REQS =3D 10094, - - /* xattr (RFC8276) */ - NFS4ERR_NOXATTR =3D 10095, - NFS4ERR_XATTR2BIG =3D 10096, - - /* can be used for internal errors */ - NFS4ERR_FIRST_FREE -}; - /* error codes for internal client use */ #define NFS4ERR_RESET_TO_MDS 12001 #define NFS4ERR_RESET_TO_PNFS 12002 diff --git a/include/linux/sunrpc/xdrgen/nfs4_1.h b/include/linux/sunrpc/xd= rgen/nfs4_1.h index 4ac54bdbd335..f761c3ddb4c7 100644 --- a/include/linux/sunrpc/xdrgen/nfs4_1.h +++ b/include/linux/sunrpc/xdrgen/nfs4_1.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */ -/* XDR specification modification time: Thu Jan 8 23:12:07 2026 */ +/* XDR specification modification time: Wed Mar 25 11:39:22 2026 */ =20 #ifndef _LINUX_XDRGEN_NFS4_1_DEF_H #define _LINUX_XDRGEN_NFS4_1_DEF_H @@ -9,15 +9,150 @@ #include #include =20 -typedef s64 int64_t; +typedef s32 int32_t; =20 typedef u32 uint32_t; =20 +typedef s64 int64_t; + +typedef u64 uint64_t; + +enum { NFS4_VERIFIER_SIZE =3D 8 }; + +enum { NFS4_FHSIZE =3D 128 }; + +enum nfsstat4 { + NFS4_OK =3D 0, + NFS4ERR_PERM =3D 1, + NFS4ERR_NOENT =3D 2, + NFS4ERR_IO =3D 5, + NFS4ERR_NXIO =3D 6, + NFS4ERR_ACCESS =3D 13, + NFS4ERR_EXIST =3D 17, + NFS4ERR_XDEV =3D 18, + NFS4ERR_NOTDIR =3D 20, + NFS4ERR_ISDIR =3D 21, + NFS4ERR_INVAL =3D 22, + NFS4ERR_FBIG =3D 27, + NFS4ERR_NOSPC =3D 28, + NFS4ERR_ROFS =3D 30, + NFS4ERR_MLINK =3D 31, + NFS4ERR_NAMETOOLONG =3D 63, + NFS4ERR_NOTEMPTY =3D 66, + NFS4ERR_DQUOT =3D 69, + NFS4ERR_STALE =3D 70, + NFS4ERR_BADHANDLE =3D 10001, + NFS4ERR_BAD_COOKIE =3D 10003, + NFS4ERR_NOTSUPP =3D 10004, + NFS4ERR_TOOSMALL =3D 10005, + NFS4ERR_SERVERFAULT =3D 10006, + NFS4ERR_BADTYPE =3D 10007, + NFS4ERR_DELAY =3D 10008, + NFS4ERR_SAME =3D 10009, + NFS4ERR_DENIED =3D 10010, + NFS4ERR_EXPIRED =3D 10011, + NFS4ERR_LOCKED =3D 10012, + NFS4ERR_GRACE =3D 10013, + NFS4ERR_FHEXPIRED =3D 10014, + NFS4ERR_SHARE_DENIED =3D 10015, + NFS4ERR_WRONGSEC =3D 10016, + NFS4ERR_CLID_INUSE =3D 10017, + NFS4ERR_RESOURCE =3D 10018, + NFS4ERR_MOVED =3D 10019, + NFS4ERR_NOFILEHANDLE =3D 10020, + NFS4ERR_MINOR_VERS_MISMATCH =3D 10021, + NFS4ERR_STALE_CLIENTID =3D 10022, + NFS4ERR_STALE_STATEID =3D 10023, + NFS4ERR_OLD_STATEID =3D 10024, + NFS4ERR_BAD_STATEID =3D 10025, + NFS4ERR_BAD_SEQID =3D 10026, + NFS4ERR_NOT_SAME =3D 10027, + NFS4ERR_LOCK_RANGE =3D 10028, + NFS4ERR_SYMLINK =3D 10029, + NFS4ERR_RESTOREFH =3D 10030, + NFS4ERR_LEASE_MOVED =3D 10031, + NFS4ERR_ATTRNOTSUPP =3D 10032, + NFS4ERR_NO_GRACE =3D 10033, + NFS4ERR_RECLAIM_BAD =3D 10034, + NFS4ERR_RECLAIM_CONFLICT =3D 10035, + NFS4ERR_BADXDR =3D 10036, + NFS4ERR_LOCKS_HELD =3D 10037, + NFS4ERR_OPENMODE =3D 10038, + NFS4ERR_BADOWNER =3D 10039, + NFS4ERR_BADCHAR =3D 10040, + NFS4ERR_BADNAME =3D 10041, + NFS4ERR_BAD_RANGE =3D 10042, + NFS4ERR_LOCK_NOTSUPP =3D 10043, + NFS4ERR_OP_ILLEGAL =3D 10044, + NFS4ERR_DEADLOCK =3D 10045, + NFS4ERR_FILE_OPEN =3D 10046, + NFS4ERR_ADMIN_REVOKED =3D 10047, + NFS4ERR_CB_PATH_DOWN =3D 10048, + NFS4ERR_BADIOMODE =3D 10049, + NFS4ERR_BADLAYOUT =3D 10050, + NFS4ERR_BAD_SESSION_DIGEST =3D 10051, + NFS4ERR_BADSESSION =3D 10052, + NFS4ERR_BADSLOT =3D 10053, + NFS4ERR_COMPLETE_ALREADY =3D 10054, + NFS4ERR_CONN_NOT_BOUND_TO_SESSION =3D 10055, + NFS4ERR_DELEG_ALREADY_WANTED =3D 10056, + NFS4ERR_BACK_CHAN_BUSY =3D 10057, + NFS4ERR_LAYOUTTRYLATER =3D 10058, + NFS4ERR_LAYOUTUNAVAILABLE =3D 10059, + NFS4ERR_NOMATCHING_LAYOUT =3D 10060, + NFS4ERR_RECALLCONFLICT =3D 10061, + NFS4ERR_UNKNOWN_LAYOUTTYPE =3D 10062, + NFS4ERR_SEQ_MISORDERED =3D 10063, + NFS4ERR_SEQUENCE_POS =3D 10064, + NFS4ERR_REQ_TOO_BIG =3D 10065, + NFS4ERR_REP_TOO_BIG =3D 10066, + NFS4ERR_REP_TOO_BIG_TO_CACHE =3D 10067, + NFS4ERR_RETRY_UNCACHED_REP =3D 10068, + NFS4ERR_UNSAFE_COMPOUND =3D 10069, + NFS4ERR_TOO_MANY_OPS =3D 10070, + NFS4ERR_OP_NOT_IN_SESSION =3D 10071, + NFS4ERR_HASH_ALG_UNSUPP =3D 10072, + NFS4ERR_CLIENTID_BUSY =3D 10074, + NFS4ERR_PNFS_IO_HOLE =3D 10075, + NFS4ERR_SEQ_FALSE_RETRY =3D 10076, + NFS4ERR_BAD_HIGH_SLOT =3D 10077, + NFS4ERR_DEADSESSION =3D 10078, + NFS4ERR_ENCR_ALG_UNSUPP =3D 10079, + NFS4ERR_PNFS_NO_LAYOUT =3D 10080, + NFS4ERR_NOT_ONLY_OP =3D 10081, + NFS4ERR_WRONG_CRED =3D 10082, + NFS4ERR_WRONG_TYPE =3D 10083, + NFS4ERR_DIRDELEG_UNAVAIL =3D 10084, + NFS4ERR_REJECT_DELEG =3D 10085, + NFS4ERR_RETURNCONFLICT =3D 10086, + NFS4ERR_DELEG_REVOKED =3D 10087, + NFS4ERR_PARTNER_NOTSUPP =3D 10088, + NFS4ERR_PARTNER_NO_AUTH =3D 10089, + NFS4ERR_UNION_NOTSUPP =3D 10090, + NFS4ERR_OFFLOAD_DENIED =3D 10091, + NFS4ERR_WRONG_LFS =3D 10092, + NFS4ERR_BADLABEL =3D 10093, + NFS4ERR_OFFLOAD_NO_REQS =3D 10094, + NFS4ERR_NOXATTR =3D 10095, + NFS4ERR_XATTR2BIG =3D 10096, + NFS4ERR_FIRST_FREE =3D 10097, +}; + +typedef enum nfsstat4 nfsstat4; + +typedef opaque attrlist4; + typedef struct { u32 count; uint32_t *element; } bitmap4; =20 +typedef u8 verifier4[NFS4_VERIFIER_SIZE]; + +typedef uint64_t nfs_cookie4; + +typedef opaque nfs_fh4; + typedef opaque utf8string; =20 typedef utf8string utf8str_cis; @@ -26,11 +161,30 @@ typedef utf8string utf8str_cs; =20 typedef utf8string utf8str_mixed; =20 +typedef utf8str_cs component4; + +typedef utf8str_cs linktext4; + +typedef struct { + u32 count; + component4 *element; +} pathname4; + struct nfstime4 { int64_t seconds; uint32_t nseconds; }; =20 +struct fattr4 { + bitmap4 attrmask; + attrlist4 attr_vals; +}; + +struct stateid4 { + uint32_t seqid; + u8 other[12]; +}; + typedef bool fattr4_offline; =20 enum { FATTR4_OFFLINE =3D 83 }; @@ -216,11 +370,98 @@ enum { FATTR4_POSIX_DEFAULT_ACL =3D 91 }; =20 enum { FATTR4_POSIX_ACCESS_ACL =3D 92 }; =20 -#define NFS4_int64_t_sz \ - (XDR_hyper) +enum notify_type4 { + NOTIFY4_CHANGE_CHILD_ATTRS =3D 0, + NOTIFY4_CHANGE_DIR_ATTRS =3D 1, + NOTIFY4_REMOVE_ENTRY =3D 2, + NOTIFY4_ADD_ENTRY =3D 3, + NOTIFY4_RENAME_ENTRY =3D 4, + NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5, +}; + +typedef enum notify_type4 notify_type4; + +struct notify_entry4 { + component4 ne_file; + struct fattr4 ne_attrs; +}; + +struct prev_entry4 { + struct notify_entry4 pe_prev_entry; + nfs_cookie4 pe_prev_entry_cookie; +}; + +struct notify_remove4 { + struct notify_entry4 nrm_old_entry; + nfs_cookie4 nrm_old_entry_cookie; +}; + +struct notify_add4 { + struct { + u32 count; + struct notify_remove4 *element; + } nad_old_entry; + struct notify_entry4 nad_new_entry; + struct { + u32 count; + nfs_cookie4 *element; + } nad_new_entry_cookie; + struct { + u32 count; + struct prev_entry4 *element; + } nad_prev_entry; + bool nad_last_entry; +}; + +struct notify_attr4 { + struct notify_entry4 na_changed_entry; +}; + +struct notify_rename4 { + struct notify_remove4 nrn_old_entry; + struct notify_add4 nrn_new_entry; +}; + +struct notify_verifier4 { + verifier4 nv_old_cookieverf; + verifier4 nv_new_cookieverf; +}; + +typedef opaque notifylist4; + +struct notify4 { + bitmap4 notify_mask; + notifylist4 notify_vals; +}; + +struct CB_NOTIFY4args { + struct stateid4 cna_stateid; + nfs_fh4 cna_fh; + struct { + u32 count; + struct notify4 *element; + } cna_changes; +}; + +struct CB_NOTIFY4res { + nfsstat4 cnr_status; +}; + +#define NFS4_int32_t_sz \ + (XDR_int) #define NFS4_uint32_t_sz \ (XDR_unsigned_int) +#define NFS4_int64_t_sz \ + (XDR_hyper) +#define NFS4_uint64_t_sz \ + (XDR_unsigned_hyper) +#define NFS4_nfsstat4_sz (XDR_int) +#define NFS4_attrlist4_sz (XDR_unsigned_int) #define NFS4_bitmap4_sz (XDR_unsigned_int) +#define NFS4_verifier4_sz (XDR_QUADLEN(NFS4_VERIFIER_SIZE)) +#define NFS4_nfs_cookie4_sz \ + (NFS4_uint64_t_sz) +#define NFS4_nfs_fh4_sz (XDR_unsigned_int + XDR_QUADLEN(NF= S4_FHSIZE)) #define NFS4_utf8string_sz (XDR_unsigned_int) #define NFS4_utf8str_cis_sz \ (NFS4_utf8string_sz) @@ -228,8 +469,17 @@ enum { FATTR4_POSIX_ACCESS_ACL =3D 92 }; (NFS4_utf8string_sz) #define NFS4_utf8str_mixed_sz \ (NFS4_utf8string_sz) +#define NFS4_component4_sz \ + (NFS4_utf8str_cs_sz) +#define NFS4_linktext4_sz \ + (NFS4_utf8str_cs_sz) +#define NFS4_pathname4_sz (XDR_unsigned_int) #define NFS4_nfstime4_sz \ (NFS4_int64_t_sz + NFS4_uint32_t_sz) +#define NFS4_fattr4_sz \ + (NFS4_bitmap4_sz + NFS4_attrlist4_sz) +#define NFS4_stateid4_sz \ + (NFS4_uint32_t_sz + XDR_QUADLEN(12)) #define NFS4_fattr4_offline_sz \ (XDR_bool) #define NFS4_open_arguments4_sz \ @@ -259,5 +509,27 @@ enum { FATTR4_POSIX_ACCESS_ACL =3D 92 }; (NFS4_aclscope4_sz) #define NFS4_fattr4_posix_default_acl_sz (XDR_unsigned_int) #define NFS4_fattr4_posix_access_acl_sz (XDR_unsigned_int) +#define NFS4_notify_type4_sz (XDR_int) +#define NFS4_notify_entry4_sz \ + (NFS4_component4_sz + NFS4_fattr4_sz) +#define NFS4_prev_entry4_sz \ + (NFS4_notify_entry4_sz + NFS4_nfs_cookie4_sz) +#define NFS4_notify_remove4_sz \ + (NFS4_notify_entry4_sz + NFS4_nfs_cookie4_sz) +#define NFS4_notify_add4_sz \ + (XDR_unsigned_int + (1 * (NFS4_notify_remove4_sz)) + NFS4_notify_entry4_s= z + XDR_unsigned_int + (1 * (NFS4_nfs_cookie4_sz)) + XDR_unsigned_int + (1 = * (NFS4_prev_entry4_sz)) + XDR_bool) +#define NFS4_notify_attr4_sz \ + (NFS4_notify_entry4_sz) +#define NFS4_notify_rename4_sz \ + (NFS4_notify_remove4_sz + NFS4_notify_add4_sz) +#define NFS4_notify_verifier4_sz \ + (NFS4_verifier4_sz + NFS4_verifier4_sz) +#define NFS4_notifylist4_sz (XDR_unsigned_int) +#define NFS4_notify4_sz \ + (NFS4_bitmap4_sz + NFS4_notifylist4_sz) +#define NFS4_CB_NOTIFY4args_sz \ + (NFS4_stateid4_sz + NFS4_nfs_fh4_sz + XDR_unsigned_int) +#define NFS4_CB_NOTIFY4res_sz \ + (NFS4_nfsstat4_sz) =20 #endif /* _LINUX_XDRGEN_NFS4_1_DEF_H */ diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h index 4273e0249fcb..289205b53a08 100644 --- a/include/uapi/linux/nfs4.h +++ b/include/uapi/linux/nfs4.h @@ -17,11 +17,9 @@ #include =20 #define NFS4_BITMAP_SIZE 3 -#define NFS4_VERIFIER_SIZE 8 #define NFS4_STATEID_SEQID_SIZE 4 #define NFS4_STATEID_OTHER_SIZE 12 #define NFS4_STATEID_SIZE (NFS4_STATEID_SEQID_SIZE + NFS4_STATEID_OTHER_SI= ZE) -#define NFS4_FHSIZE 128 #define NFS4_MAXPATHLEN PATH_MAX #define NFS4_MAXNAMLEN NAME_MAX #define NFS4_OPAQUE_LIMIT 1024 --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 D746F37CD4D; Fri, 22 May 2026 12:29:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452956; cv=none; b=eKZ+geHl1GFbn241FADKkDU7H0/3GrHgFqskmE+xK6hepFh+VMK1qwX2RT40FSnSNTlrxahFYmAuz7snSapTenVi+Kp1FrubYBuUJS4Pk6W5tqRKrRsb6R5dk9+0YEol2yVz9uyO7/C/pkC+CWI54qO9R4lBRJHwrV//bKlODqA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452956; c=relaxed/simple; bh=YLh4/lMM1FLFsNW282HugdeM6AzL2tOPs8cUBDQeTEU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AJqHM1wTHW59x6H2AEkwtZjz4bi2i/02VndclvZxJYkJNr32ymiDNxDoJKGwBg3OyO8sOBXQ0UBAWmQq4zvBk4UidV6oSgSh9cuQm7hf/JmY8DNwJbzPcjxZB2ZnbvHFuP5h80NrSomJPYjwZbuh2V07TpLc7Y/cNCqwoIGpGKY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JhxeIAMW; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JhxeIAMW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 147981F000E9; Fri, 22 May 2026 12:29:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452954; bh=aAgM8vwRcWxiJmuLj41yAuRh7mP2E+WvonVFr4ezXks=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=JhxeIAMWJSjQa7xApj5ol1JHSQDFI3dqZ4ig+i5iKT2OXzQU+T/jN7MVHhN0PTR3P ECYM3LXzwEWoskzSZPLnRI5r2ZBdNbZzywXMRPaLOtHCT2EgnbIUYSUURB25TiW9ID DY3vGg5uSB2fbLpi7OZW7StqPxS/vEIcWbqE0B3HycA3hFwB7LBFwUaKfIXQj38HsS xANKsXamQhLxYBhlmbzg9CSvjzSiZ9Ofg0liPjQ6zgpMqVN2R2RB16l1cHWvE6PIdQ MShd57deNxOSvGWjny0sJ3HzpoCfq48SFjU+Pk2Ie6sKsYcdxwxHJc2DSWiPVt6mnJ 8eojnYUbHDtEw== From: Jeff Layton Date: Fri, 22 May 2026 08:28:52 -0400 Subject: [PATCH v4 03/21] nfs_common: add new NOTIFY4_* flags proposed in RFC8881bis Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-3-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=4154; i=jlayton@kernel.org; h=from:subject:message-id; bh=YLh4/lMM1FLFsNW282HugdeM6AzL2tOPs8cUBDQeTEU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwNcEdbzPr1iYqi2n9VQZizyuxg1vs0f2FFL KwIVSNbteuJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMDQAKCRAADmhBGVaC FeuPEACMFjZyCivfHdG/ha0YaAzGhS2Kj5/etvIg/UkCVuy62rNm+72nuWG3mkMLC44Jr619nTg NKMNvbHQYLp4gLhRmZQrlT1YwujuMmkb+OWcm0na85fMHIT4F0st2JeCMUHU10muc1Ahoc1NunK cPLZTb4/n399ZY/OcFbv2G/+XKjmsrkQo9veyujFx+iszJ9MzOlbxf6qRAu8sze4vfpg12z4h8a CVzs3W+U0XYSLB6Xdsb7ZR6fPwLszr4Gbn5s2VjgUX4ko9c61GtPS2IK9AEDzCIDGDsA6kRwSFI P/fWInox1Hqtkeml0We8S9KyLrAcYr5Jw2pbYIc67wm8N1ajSdEI+bQk250tjGuWvnCtkBiDYAk xCrI5cBP4IymqKYRMbroNitHq+MkxX3UM1vlg+tn3HXe8L2AIEwIfxdtIisSRr9m3J9nqGUZNA+ BNZCSSBY7Dv/Pds3N+9mCUqbWX37ONACD4m493y5aR9tP721kB2skDjlKFcxTaz7dzFjfMIJg6k xzjIkJDOyEUpDxPiJPzhumgIQyXkK4cQIc6325N6BYGV7kXXZi4hxPpJzQRgUWH70/I/jb6dnWk cPohAElSsDmg8AzvirsD7YVj+J6/y1QHAvGinqCOSmgISM6oODtTrd13YOCtZPMha9/y2GOqQqK NRTivlK/g4mBPcw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 RFC8881bis adds some new flags to GET_DIR_DELEGATION that we very much need to support. Signed-off-by: Jeff Layton --- Documentation/sunrpc/xdr/nfs4_1.x | 16 +++++++++++++++- fs/nfsd/nfs4xdr_gen.c | 13 ++++++++++++- fs/nfsd/nfs4xdr_gen.h | 2 +- include/linux/sunrpc/xdrgen/nfs4_1.h | 13 ++++++++++++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/Documentation/sunrpc/xdr/nfs4_1.x b/Documentation/sunrpc/xdr/n= fs4_1.x index 632f5b579c39..aa14b590b524 100644 --- a/Documentation/sunrpc/xdr/nfs4_1.x +++ b/Documentation/sunrpc/xdr/nfs4_1.x @@ -416,7 +416,21 @@ enum notify_type4 { NOTIFY4_REMOVE_ENTRY =3D 2, NOTIFY4_ADD_ENTRY =3D 3, NOTIFY4_RENAME_ENTRY =3D 4, - NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5 + NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5, + /* + * Added in NFSv4.1 bis document + */ + NOTIFY4_GFLAG_EXTEND =3D 6, + NOTIFY4_AUFLAG_VALID =3D 7, + NOTIFY4_AUFLAG_USER =3D 8, + NOTIFY4_AUFLAG_GROUP =3D 9, + NOTIFY4_AUFLAG_OTHER =3D 10, + NOTIFY4_CHANGE_AUTH =3D 11, + NOTIFY4_CFLAG_ORDER =3D 12, + NOTIFY4_AUFLAG_GANOW =3D 13, + NOTIFY4_AUFLAG_GALATER =3D 14, + NOTIFY4_CHANGE_GA =3D 15, + NOTIFY4_CHANGE_AMASK =3D 16 }; =20 /* Changed entry information. */ diff --git a/fs/nfsd/nfs4xdr_gen.c b/fs/nfsd/nfs4xdr_gen.c index 5e656d6bbb8e..80369139ef7e 100644 --- a/fs/nfsd/nfs4xdr_gen.c +++ b/fs/nfsd/nfs4xdr_gen.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Generated by xdrgen. Manual edits will be lost. // XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x -// XDR specification modification time: Wed Mar 25 11:39:22 2026 +// XDR specification modification time: Wed Mar 25 11:40:02 2026 =20 #include =20 @@ -590,6 +590,17 @@ xdrgen_decode_notify_type4(struct xdr_stream *xdr, not= ify_type4 *ptr) case NOTIFY4_ADD_ENTRY: case NOTIFY4_RENAME_ENTRY: case NOTIFY4_CHANGE_COOKIE_VERIFIER: + case NOTIFY4_GFLAG_EXTEND: + case NOTIFY4_AUFLAG_VALID: + case NOTIFY4_AUFLAG_USER: + case NOTIFY4_AUFLAG_GROUP: + case NOTIFY4_AUFLAG_OTHER: + case NOTIFY4_CHANGE_AUTH: + case NOTIFY4_CFLAG_ORDER: + case NOTIFY4_AUFLAG_GANOW: + case NOTIFY4_AUFLAG_GALATER: + case NOTIFY4_CHANGE_GA: + case NOTIFY4_CHANGE_AMASK: break; default: return false; diff --git a/fs/nfsd/nfs4xdr_gen.h b/fs/nfsd/nfs4xdr_gen.h index 503fe2ccba51..092a1ed399c7 100644 --- a/fs/nfsd/nfs4xdr_gen.h +++ b/fs/nfsd/nfs4xdr_gen.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */ -/* XDR specification modification time: Wed Mar 25 11:39:22 2026 */ +/* XDR specification modification time: Wed Mar 25 11:40:02 2026 */ =20 #ifndef _LINUX_XDRGEN_NFS4_1_DECL_H #define _LINUX_XDRGEN_NFS4_1_DECL_H diff --git a/include/linux/sunrpc/xdrgen/nfs4_1.h b/include/linux/sunrpc/xd= rgen/nfs4_1.h index f761c3ddb4c7..537504069f24 100644 --- a/include/linux/sunrpc/xdrgen/nfs4_1.h +++ b/include/linux/sunrpc/xdrgen/nfs4_1.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */ -/* XDR specification modification time: Wed Mar 25 11:39:22 2026 */ +/* XDR specification modification time: Wed Mar 25 11:40:02 2026 */ =20 #ifndef _LINUX_XDRGEN_NFS4_1_DEF_H #define _LINUX_XDRGEN_NFS4_1_DEF_H @@ -377,6 +377,17 @@ enum notify_type4 { NOTIFY4_ADD_ENTRY =3D 3, NOTIFY4_RENAME_ENTRY =3D 4, NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5, + NOTIFY4_GFLAG_EXTEND =3D 6, + NOTIFY4_AUFLAG_VALID =3D 7, + NOTIFY4_AUFLAG_USER =3D 8, + NOTIFY4_AUFLAG_GROUP =3D 9, + NOTIFY4_AUFLAG_OTHER =3D 10, + NOTIFY4_CHANGE_AUTH =3D 11, + NOTIFY4_CFLAG_ORDER =3D 12, + NOTIFY4_AUFLAG_GANOW =3D 13, + NOTIFY4_AUFLAG_GALATER =3D 14, + NOTIFY4_CHANGE_GA =3D 15, + NOTIFY4_CHANGE_AMASK =3D 16, }; =20 typedef enum notify_type4 notify_type4; --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 5231F38AC79; Fri, 22 May 2026 12:29:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452957; cv=none; b=JcD9EuR/JCDOGxSjKD2j1YhsfeWjbY+8aEJ/qiVEo9q8f2ozXyW1K8F3J1TBK53lzIelA7fwmWXpBzwu6Ip8fw8nznQyFR2b8QaVIUUrSdGqKBP8jlLmYpqmkuohsgZc0AzqhcCkabtCPdgSQ5WoYPkj+FThz8etBHlQR7XZk1o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452957; c=relaxed/simple; bh=6+xgS9Oi//iUZD1ri3viy4fOOkWtg6yKfKkrsgbZtwo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YjomVdn6PTWXj5N8zl3Dopn2Z5T8JRwjxGLwr5Hyak1LFU9+sjuj64ggwfov6sYOw9dbdDbw2OgUZ6V2CqiBRiHrDaKPYsOEw2seMZWjkIHQEleP7fcvLWU4M3TXPjz0G/LzaKihBxontz9lc7GBUGrAdIXgRz1IldTLa7OIVZ0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=A4o8ZFNf; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="A4o8ZFNf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BF9081F00A3D; Fri, 22 May 2026 12:29:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452956; bh=yn+E0MiyGHjI4tTcZW7VzxHDKSKAvs1i4UMk8wxbinU=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=A4o8ZFNfgK1M4UcKU0rzETyTnyHkLYY7IOngI8GZx0aVRB0UlaeMRnybyQcepF2S5 dqGbiyDkqkxfOISPn3lRzWwlxkPyfErH3hyUX4JqA3govP3kNPNtfmW7lyAmfun3t1 78sy6fIcpe+cfGjv+cPwx8zKmV0W5Rl7qwUp7SQSExEfL+39kgTBupBax/7WU19wgV PdeX0MamXzQ0JjIk558s86In5shQRrQX1oKYPi9K27jp+mjiFfOhf5bGh/+rgo1C00 PqjTHpYR32+Ja0Vyd6s+Qo23vAuEVIZ/KpPskft+M0n3KJYmPfX2DijTc1YM1ihTti jUZiX9cq1NPaQ== From: Jeff Layton Date: Fri, 22 May 2026 08:28:53 -0400 Subject: [PATCH v4 04/21] nfsd: allow nfsd to get a dir lease with an ignore mask Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-4-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2342; i=jlayton@kernel.org; h=from:subject:message-id; bh=6+xgS9Oi//iUZD1ri3viy4fOOkWtg6yKfKkrsgbZtwo=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwNyS3iS+O65mi02G1HOQSk/h3hjTqaiETd1 NqTW1f/ieaJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMDQAKCRAADmhBGVaC FYlFD/kBkidjyXGjn0htQxSzguYDgexBj2U1yjoFPYCyqUnavfBfi97GhESk0DQZFvcH8y7tUBN +7I1+/AanV48puiTTWpdl4WI2ZYu+eKcIWS4bx8Gqi/ipMEimSeJ1EuDiwVtxXHDIPgWrDrLMrJ MA/xd2BxwMZfgcJHmotRQtQ4jtE06BdnnZXXZikkcrup1Sj7sAjWObqRTxOL5IaIbjnf1GAX1Oj 72Dpb689I8lu31aPOcEmvj746sqaG2DZNhRJTZnd4m+nGdwx9/HyXPtgDod7u/B4WOzicp3x0Qx +xk6tH8cUH7jQe00dQ8iFHmvMWb/wgkXVPEt4sOlgijMRp6uV39jHcScL7SytZMDyzN9fyxbp46 sBul34A4v4oP5a2FM91TycPVVSqMFSWiPqDBWkAK/JXXcsBCzNYn5lPTo+KDTnf7IJtVVuQ3qDN JrAUUhP0VJnO8fLbREQ0RVSE5VvP1xNSjK8ZtKH3YQZZ13Vumy4SOqrsGljgNT133ftxdmLqUnR KASOB5gTFAa7pey8zzeSY+RkZiNi9cr6KSGdKk7/Lk0lCdCN6HiSdEfBIotYxPFLLnm8b3vjHaX Ka8Z2Ml6wh+gv9r1qFiYzJLE0JfFyNbCPT3dFekgOV9T0CvPRNDfmBbUv+7IDIaoulRFz/lFFus LHj4Ru6uF5KxPZQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 When requesting a directory lease, enable the FL_IGN_DIR_* bits that correspond to the requested notification types. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 67e163ee13a2..2a34ba457b74 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -6048,7 +6048,22 @@ static bool nfsd4_cb_channel_good(struct nfs4_client= *clp) return clp->cl_minorversion && clp->cl_cb_state =3D=3D NFSD4_CB_UNKNOWN; } =20 -static struct file_lease *nfs4_alloc_init_lease(struct nfs4_delegation *dp) +static unsigned int +nfsd_notify_to_ignore(u32 notify) +{ + unsigned int mask =3D 0; + + if (notify & BIT(NOTIFY4_REMOVE_ENTRY)) + mask |=3D FL_IGN_DIR_DELETE; + if (notify & BIT(NOTIFY4_ADD_ENTRY)) + mask |=3D FL_IGN_DIR_CREATE; + if (notify & BIT(NOTIFY4_RENAME_ENTRY)) + mask |=3D FL_IGN_DIR_RENAME; + + return mask; +} + +static struct file_lease *nfs4_alloc_init_lease(struct nfs4_delegation *dp= , u32 notify) { struct file_lease *fl; =20 @@ -6056,7 +6071,7 @@ static struct file_lease *nfs4_alloc_init_lease(struc= t nfs4_delegation *dp) if (!fl) return NULL; fl->fl_lmops =3D &nfsd_lease_mng_ops; - fl->c.flc_flags =3D FL_DELEG; + fl->c.flc_flags =3D FL_DELEG | nfsd_notify_to_ignore(notify); fl->c.flc_type =3D deleg_is_read(dp->dl_type) ? F_RDLCK : F_WRLCK; fl->c.flc_owner =3D (fl_owner_t)dp; fl->c.flc_pid =3D current->tgid; @@ -6273,7 +6288,7 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, if (stp->st_stid.sc_export) dp->dl_stid.sc_export =3D exp_get(stp->st_stid.sc_export); =20 - fl =3D nfs4_alloc_init_lease(dp); + fl =3D nfs4_alloc_init_lease(dp, 0); if (!fl) goto out_clnt_odstate; =20 @@ -9642,12 +9657,11 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cst= ate, dp->dl_stid.sc_export =3D exp_get(cstate->current_fh.fh_export); =20 - fl =3D nfs4_alloc_init_lease(dp); + fl =3D nfs4_alloc_init_lease(dp, gdd->gddr_notification[0]); if (!fl) goto out_put_stid; =20 - status =3D kernel_setlease(nf->nf_file, - fl->c.flc_type, &fl, NULL); + status =3D kernel_setlease(nf->nf_file, fl->c.flc_type, &fl, NULL); if (fl) locks_free_lease(fl); if (status) --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 4ABE438237D; Fri, 22 May 2026 12:29:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452959; cv=none; b=eUgNR9VMkY1jW4ZPoBic4W2NmcgVmhY4+EcSOcEGLLWsiCddAkviqh+uRS/UYxwqNGn+f0GUpxNLtsEPWLqFAU/KAYSFZRvi3qSr0q7qYhXFmaKHGoR10Dnb2R0V51oV/zcqYoGPGXkk+aYHqsgqyxD+N0EndFJM7B53nXZecTc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452959; c=relaxed/simple; bh=niHRetJpdk8GdDu45WpThrb5QNns7NwqVudj1Z7UsxI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ds3x2TMoyaLx9FjVCbVH4gjITziPAxltsEmkITkfP3tfcOFJKq93MwZIbf2zWkbXCZeMVdpPehv7Ysk+LRW1z4eljjzkPPK9JY9+hzzAmHxb1Cpc3Dg/yyR4DJKQuqOgpCijBNzorm1QlT8jEC0NzDir0SIauxx4ureM9SI4dpg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HbDzxpd1; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HbDzxpd1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 778F61F00A3E; Fri, 22 May 2026 12:29:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452957; bh=HYxzjQeJXDqfECCwC1Wng+6TWYv7L4DR2K7Z13hoaks=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=HbDzxpd1ec7V+vXBfNmYvpOMPE53/wW11i8BrwP48TbiTwdC2T74kt6MuKzVDREsv cI3VUIoR7Lbv3rnTf37XaBy7VUTzAU79/npS6AU4VYdJwosnxyl8dJxg7F7h2sKB2I 8ueM4pxCMO0DBpL+sZQCqt8pi5ablsieRW5VAbPFKq/sahN7v/bWC/Et+yayWHOF/D 58bZ1BF8/qYG0UOxflehbKxTOo8GmkuSbPq1LAaO+hhMwPLPmC0Y5jKhBawqyEbFAD SjTnglkCa9Y5po4dBjXG4IrDEUOe65/U9cdISMA2lRdULro+uSbZMKQMDNKPnSLapk t21kTDKMD9Pgg== From: Jeff Layton Date: Fri, 22 May 2026 08:28:54 -0400 Subject: [PATCH v4 05/21] nfsd: update the fsnotify mark when setting or removing a dir delegation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-5-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2134; i=jlayton@kernel.org; h=from:subject:message-id; bh=niHRetJpdk8GdDu45WpThrb5QNns7NwqVudj1Z7UsxI=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwOHPX4H/JbJEfH4Mbi05HZ9gWCjH24ntIb0 P8BCcAccA6JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMDgAKCRAADmhBGVaC FQ2uD/4jHX82IdxjK2/OjFButxydi9cmrOXH9n2BhoUbAhB50lmFLTcJLSMztFrND4855VEUdbk 2Qu5j4Awnrv0ViPWbVwgZVVqm4ye0sCtFdUVeefwgsBaKoZ5ns/052ZYZCeUxMQ2c6aMVovBz21 7ysNIfTyKClPXmTDZf9+Tq5IzZiZcXezu6K+q/X62lrAEG9IugpZcqwJqDBUy7l5TDaM4AsDKC4 LuY+WrRlfzct2wFzv6mcqDUr6MQPoHw55gL0jlvM+q+Ea8vA2hPolM/82q4/lJijOS8HQQqgamr 57FlDxp+U0KCJXoDxaO5NFUc90FLDuXkxwVI1e3kkBXtuWY38RUhO8flXpZmwfP+lSxTZqxCZRi ghBkMjO9CYW3AAIGgTv9Mrd+APWQrVMKk1ErZkkDfbA8S8jxbz+hyZCkiNyiX97oLQ+czyMlsJh feHKrd79f46hCSLrEWRGAyogZrdiL7I5TgfXHTynbkMfBrj1T2uLvJz7U9Xpo2u8QEztNmwvs0c KcdmBjVv5YB6OmOEW8BUokhX/1kMiLYJYkKXyDrlA9S+Dl6E80X/0CjgvHWJFOrIA3Igs+PuD2z GlNPuEUbubiBkttH+VD6Olyl2MlOMFO7L1arogoIgTndGHWi9lWrJQhSmDHmJ+RJeDXDlXRUSHF WiRKzwn7dGrijOw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a new helper function that will update the mask on the nfsd_file's fsnotify_mark to be a union of all current directory delegations on an inode. Call that when directory delegations are added or removed. Reviewed-by: Jan Kara Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2a34ba457b74..f559ce4422da 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1246,6 +1246,37 @@ static void nfsd4_finalize_deleg_timestamps(struct n= fs4_delegation *dp, struct f nfsd_update_cmtime_attr(f, ATTR_ATIME); } =20 +static void nfsd_fsnotify_recalc_mask(struct nfsd_file *nf) +{ + struct fsnotify_mark *mark =3D &nf->nf_mark->nfm_mark; + struct inode *inode =3D file_inode(nf->nf_file); + u32 lease_mask, set =3D 0, clear =3D 0; + + /* This is only needed when adding or removing dir delegs */ + if (!S_ISDIR(inode->i_mode)) + return; + + /* Set up notifications for any ignored delegation events */ + lease_mask =3D inode_lease_ignore_mask(inode); + + if (lease_mask & FL_IGN_DIR_CREATE) + set |=3D FS_CREATE | FS_MOVED_TO; + else + clear |=3D FS_CREATE | FS_MOVED_TO; + + if (lease_mask & FL_IGN_DIR_DELETE) + set |=3D FS_DELETE | FS_MOVED_FROM; + else + clear |=3D FS_DELETE | FS_MOVED_FROM; + + if (lease_mask & FL_IGN_DIR_RENAME) + set |=3D FS_RENAME; + else + clear |=3D FS_RENAME; + + fsnotify_modify_mark_mask(mark, set, clear); +} + static void nfs4_unlock_deleg_lease(struct nfs4_delegation *dp) { struct nfs4_file *fp =3D dp->dl_stid.sc_file; @@ -1255,6 +1286,7 @@ static void nfs4_unlock_deleg_lease(struct nfs4_deleg= ation *dp) =20 nfsd4_finalize_deleg_timestamps(dp, nf->nf_file); kernel_setlease(nf->nf_file, F_UNLCK, NULL, (void **)&dp); + nfsd_fsnotify_recalc_mask(nf); put_deleg_file(fp); } =20 @@ -9682,6 +9714,7 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstat= e, =20 if (!status) { put_nfs4_file(fp); + nfsd_fsnotify_recalc_mask(nf); return dp; } =20 --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 B585F393DEE; Fri, 22 May 2026 12:29:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452960; cv=none; b=RVy3JGPGw1rJOdxMygQRu4t32lVfcNJx4Z+skWLFNpJuof22QJ+Hp2hUfANPMty7zlazasXfBb57omo03mRP5lZhF10YpN2+eYyCYssap+C4EU3Y6KQGWPXFA46b7nGB/t9ux7u5MTRpWQVMVHle02O0nITNrbW12GokjNuDodU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452960; c=relaxed/simple; bh=z1IAS0dOzP5h/+agcTRSLuoAeWW9RbzY4nCWCh5mwMI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VlFnO2bVB3d7s6Wl6T1jFI3pZ1ULylxFvNcUBD4ufcbmN60WpZIesy9VOxwI5raORsQPBcZrjr9CkzKhAOYzvY5QqVO0z1X/VpNMFQHH1TDyizb93cops4cjad4TmFa9JwDEX88ypY5EXJx3njSGH/MJa/wd+IXJmVf20xbWvmE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HUG+ZSMr; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HUG+ZSMr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2F6001F000E9; Fri, 22 May 2026 12:29:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452959; bh=yfKc4GvlDUZVKTDf5ZDFEDag7Qqh0lwgFrnvTVJtlBk=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=HUG+ZSMr/9oQiKMWWJEoX7LEEsXaMa0zFvk1M5eSEviMdpnwWkTQkpVNcS+DEJt8g M5Z0K2oipF55HJqo20jilqAYBAocQ7a9M4RoHtheWQtgc39zXIg8xshuloamvwCgaJ faRsaWWlPPqWqLqB8WmZmUMAt1dWl9pOMWtn1/6C48lcpAij1yzER5WwVmN00TknGb AIX/C4Ek3UZCuqX3Hffkv3I7L2HsaqGjm/HRxo+59gi15PQryu4Vfu1P/XG2an4+5o fUwJoIDNrqaoYCHtqEDx8tjkS0fG0ZFw2DoRDRr2a7VOTtO0bQ5eNY5HVE1imyrPT0 +ojYCeVGP6odg== From: Jeff Layton Date: Fri, 22 May 2026 08:28:55 -0400 Subject: [PATCH v4 06/21] nfsd: make nfsd4_callback_ops->prepare operation bool return Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-6-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3301; i=jlayton@kernel.org; h=from:subject:message-id; bh=z1IAS0dOzP5h/+agcTRSLuoAeWW9RbzY4nCWCh5mwMI=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwOVelK4Shz5MZ1EgkR9pUo7PZ0ksD3Jey+B thTRiWXlU2JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMDgAKCRAADmhBGVaC FchcD/9Tjqo82kodTub/91fSnT67Gb2D39ktZ3wydGx5WS8MPb1ChQ9gSsPSMXYzpc3xbjbvU3U +YzJwzV8cSu0f7NkJxta6wACW5/nxLLHSQ5W52UOJG4hgmboOxEFfiI0dBvMkM5qLRWGHb8lJ9a 1Kd/r2ZG0VDovzGCV2x0szhTn5yGKn0L5yUX84hZIL5jbEutPliJ3ch9a6XaV3ZXYE736H7oRGj lx5sFSuwtyOciLC2Bswblv+0NoUYcqbh7KLuq2QfQcVuGe+tXsp8oZC3GPrsoQQY6K63I+aEhKP dFs8Qx3KzBwn+n6Fb1njw42BioMjbMTVE2zQpaOJOK6h+0kvfujQrvrfp9mIUuuS/13fLhV63z2 yNmwh5q6+zvyYfscJibbAW4hVkwSc1MkesNO1/YT4zD2ifEYNI1FCQN/cUGRTYoBYopkyoIsn1l en2nBkBqzYEEF1emTR5zlzw5EyOnmyxA6DjAj65cMbPABz3U3qcRaxbUBEg43jIV6rS5w7Qr6aQ Ztz4cRMuzg2RB18ZQXTqqVtc9oo1gL3tY8eh8U9a9jJJ8AP/MWnGWiyABtoy+U0ADKxSNYRn8QL rJ5K5ZJ11Mdhm1wmBPTkfA1aZW3PmPWr7KjhpjNEdT9WRFNV9Z5+AGtA0TTJnQLjmPa0VziXMpq fjK+0cTs+giCeYw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 For a CB_NOTIFY operation, we need to stop processing the callback if an allocation fails. Change the ->prepare callback operation to return true if processing should continue, and false otherwise. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4callback.c | 5 ++++- fs/nfsd/nfs4layouts.c | 3 ++- fs/nfsd/nfs4state.c | 6 ++++-- fs/nfsd/state.h | 6 +++--- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 50827405468d..25bbf5b8814d 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -1715,7 +1715,10 @@ nfsd4_run_cb_work(struct work_struct *work) =20 if (!test_and_clear_bit(NFSD4_CALLBACK_REQUEUE, &cb->cb_flags)) { if (cb->cb_ops && cb->cb_ops->prepare) - cb->cb_ops->prepare(cb); + if (!cb->cb_ops->prepare(cb)) { + nfsd41_destroy_cb(cb); + return; + } } =20 cb->cb_msg.rpc_cred =3D clp->cl_cb_cred; diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index f34320e4c2f4..e3984c90792e 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -652,7 +652,7 @@ nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls, st= ruct nfsd_file *file) } } =20 -static void +static bool nfsd4_cb_layout_prepare(struct nfsd4_callback *cb) { struct nfs4_layout_stateid *ls =3D @@ -661,6 +661,7 @@ nfsd4_cb_layout_prepare(struct nfsd4_callback *cb) mutex_lock(&ls->ls_mutex); nfs4_inc_and_copy_stateid(&ls->ls_recall_sid, &ls->ls_stid); mutex_unlock(&ls->ls_mutex); + return true; } =20 static int diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index f559ce4422da..beb6e95a1e4d 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -357,12 +357,13 @@ remove_blocked_locks(struct nfs4_lockowner *lo) } } =20 -static void +static bool nfsd4_cb_notify_lock_prepare(struct nfsd4_callback *cb) { struct nfsd4_blocked_lock *nbl =3D container_of(cb, struct nfsd4_blocked_lock, nbl_cb); locks_delete_block(&nbl->nbl_lock); + return true; } =20 static int @@ -5561,7 +5562,7 @@ bool nfsd_wait_for_delegreturn(struct svc_rqst *rqstp= , struct inode *inode) return timeo > 0; } =20 -static void nfsd4_cb_recall_prepare(struct nfsd4_callback *cb) +static bool nfsd4_cb_recall_prepare(struct nfsd4_callback *cb) { struct nfs4_delegation *dp =3D cb_to_delegation(cb); struct nfsd_net *nn =3D net_generic(dp->dl_stid.sc_client->net, @@ -5582,6 +5583,7 @@ static void nfsd4_cb_recall_prepare(struct nfsd4_call= back *cb) list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); } spin_unlock(&nn->deleg_lock); + return true; } =20 static int nfsd4_cb_recall_done(struct nfsd4_callback *cb, diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index dec83e92650d..e1c40f8b5d01 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -98,9 +98,9 @@ struct nfsd4_callback { }; =20 struct nfsd4_callback_ops { - void (*prepare)(struct nfsd4_callback *); - int (*done)(struct nfsd4_callback *, struct rpc_task *); - void (*release)(struct nfsd4_callback *); + bool (*prepare)(struct nfsd4_callback *cb); + int (*done)(struct nfsd4_callback *cb, struct rpc_task *task); + void (*release)(struct nfsd4_callback *cb); uint32_t opcode; }; =20 --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 9E20B38E8A5; Fri, 22 May 2026 12:29:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452962; cv=none; b=SVqZBaR1tJeVks/xXs8k9MDS3a/GXjlJz3hlhkBzZJFVFO8wdn3KrJrFNdFG91/By7g2mOAn9q7xFPO603iaKXsAHVGo1GwM79eP24zsih2ArYr+JW+SVrz9baW8iO9FL4o0z9mhCkSle2jsRTFHoGoTYKCft7ETI5NDWPHZ394= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452962; c=relaxed/simple; bh=b1rU6ZAGMx709xUdqTWwkbd1Zwx96RNeV+LNlMCfsIs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Pnx0/W9jr20QG1eZZZ876bHzEfngNrSZ+WhRdOoZtYSgLh0W2bLPOZ0sou90+Q4Ey/NmUb95DWSlltnA8JDvpvihNGL9rGPZi1jEh5INDLNwswr2u3YeQ75bPhsROgcviyfj7jOTzoPa/dF0TD9vI9VUGDj2NG3qCR8UK3s476o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Pskq59gK; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Pskq59gK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D9F201F0155A; Fri, 22 May 2026 12:29:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452961; bh=4LN8CBPtlSu0h1hjRMQR5ihtJ8gQEm1OuiggHng7lj4=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=Pskq59gKO7QScu2KFodiQoaP9Rot9rM81ScZ5rr9JrixEV5YesVNh2MPot14225kO 5Rb9KxVPiLTRecdIOoiIBMIrxC9HWpI++3vKKxCkmvFkXmP1r4lvck1l66X2DaQ+qu ytPqs4CWl8iiMSNLXEikyvqATmMazl8fxA3/dk0lezy2nfyt++/CiDoANs3GSwxjYJ N/+ULcnOdeN7g2eRz7EgI9V2qgqLCggjbMXPUpReJm0AqMflCWhryMRE6kLdEXmHMB gf5OZ3Xyq8ZFG3rARoZ8hjr3tokEBsk9bV0XboIoyJxtXUmNlYbKaMJ3hy3V8lK8af 3bmUV1tORDUTg== From: Jeff Layton Date: Fri, 22 May 2026 08:28:56 -0400 Subject: [PATCH v4 07/21] nfsd: add callback encoding and decoding linkages for CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-7-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3990; i=jlayton@kernel.org; h=from:subject:message-id; bh=b1rU6ZAGMx709xUdqTWwkbd1Zwx96RNeV+LNlMCfsIs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwOkhcogk+Qxy6TDIl9z7Y1TWQNG3Fve7SJF ri1zcxfIQeJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMDgAKCRAADmhBGVaC Ff8QD/kBNWykl8tScnfoshyW8rKhjTQHRMreOWaC8mTnOIV1Taze3sWrV57egDhhpWAeKpa7PE6 /oTEUbjjL7F1cHWA+2vgAIGZ4JyMIwD/PcneLpZpOa7O1KdlDMMg3TIEjuKmnh8LaUSaOTNVZqC v9LvvIe2guK4JIjonnbGskqZPex9djk9CrI00/7+2HW55nmb/+S+OCALrZvfctGSPPjOU4p1X9Y lOHUlMJGP1MS2vS/3Gjxk0mBfcoZ+qVLFu0u5X5exvwClbmh04T1brslYxNqYQlBmZ/WD6neD5y YoTzFpb+mhaW6TwViTuo+ukuJBDB8PmVEnzvIKUOZGMDJ3C5T2pXABg8Y1bV+WxgkCjiHdOFB3E dRpxA+DQHu+QSVsxSTsrq9+g4qsELxg79nLWcNNW1gYrAe4JPHzsXWJkP2AtjsgBJe/pNmI/VFU N7f48GgaLoixB4T9o6nONQ5WHFlIF+dfwINnu7004xuWvPsEr0R7qVwlLH2KXtfYdIsJu6B6upR V6EDIC8KeCqCguOfd/jqsU6ICLKy1lR4GUAMPfsH9wkf7Zug623TiAB0Mxmz5a4NobUaBGLKeVy +MWjxf/QQ3WnwVtO/3PwIvL2mI2JcbbD+BWCwks0yG4d7gnmJG/NZHAsYcy7dqTiFJfxW7WT1Pq eJDzaDd+ytkyURA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add routines for encoding and decoding CB_NOTIFY messages. These call into the code generated by xdrgen to do the actual encoding and decoding. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4callback.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/state.h | 8 ++++++++ fs/nfsd/xdr4cb.h | 12 ++++++++++++ 3 files changed, 66 insertions(+) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 25bbf5b8814d..ea3e7deb06fa 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -865,6 +865,51 @@ static void encode_stateowner(struct xdr_stream *xdr, = struct nfs4_stateowner *so xdr_encode_opaque(p, so->so_owner.data, so->so_owner.len); } =20 +static void nfs4_xdr_enc_cb_notify(struct rpc_rqst *req, + struct xdr_stream *xdr, + const void *data) +{ + const struct nfsd4_callback *cb =3D data; + struct nfs4_cb_compound_hdr hdr =3D { + .ident =3D 0, + .minorversion =3D cb->cb_clp->cl_minorversion, + }; + struct CB_NOTIFY4args args =3D { }; + + WARN_ON_ONCE(hdr.minorversion =3D=3D 0); + + encode_cb_compound4args(xdr, &hdr); + encode_cb_sequence4args(xdr, cb, &hdr); + + /* + * FIXME: get stateid and fh from delegation. Inline the cna_changes + * buffer, and zero it. + */ + WARN_ON_ONCE(!xdrgen_encode_CB_NOTIFY4args(xdr, &args)); + + hdr.nops++; + encode_cb_nops(&hdr); +} + +static int nfs4_xdr_dec_cb_notify(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + void *data) +{ + struct nfsd4_callback *cb =3D data; + struct nfs4_cb_compound_hdr hdr; + int status; + + status =3D decode_cb_compound4res(xdr, &hdr); + if (unlikely(status)) + return status; + + status =3D decode_cb_sequence4res(xdr, cb); + if (unlikely(status || cb->cb_seq_status)) + return status; + + return decode_cb_op_status(xdr, OP_CB_NOTIFY, &cb->cb_status); +} + static void nfs4_xdr_enc_cb_notify_lock(struct rpc_rqst *req, struct xdr_stream *xdr, const void *data) @@ -1026,6 +1071,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[]= =3D { #ifdef CONFIG_NFSD_PNFS PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout), #endif + PROC(CB_NOTIFY, COMPOUND, cb_notify, cb_notify), PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock), PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload), PROC(CB_RECALL_ANY, COMPOUND, cb_recall_any, cb_recall_any), diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index e1c40f8b5d01..790282781243 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -190,6 +190,13 @@ struct nfs4_cb_fattr { u64 ncf_cur_fsize; }; =20 +/* + * FIXME: the current backchannel encoder can't handle a send buffer longer + * than a single page (see bc_alloc/bc_free). + */ +#define NOTIFY4_EVENT_QUEUE_SIZE 3 +#define NOTIFY4_PAGE_ARRAY_SIZE 1 + /* * Represents a delegation stateid. The nfs4_client holds references to th= ese * and they are put when it is being destroyed or when the delegation is @@ -774,6 +781,7 @@ enum nfsd4_cb_op { NFSPROC4_CLNT_CB_NOTIFY_LOCK, NFSPROC4_CLNT_CB_RECALL_ANY, NFSPROC4_CLNT_CB_GETATTR, + NFSPROC4_CLNT_CB_NOTIFY, }; =20 /* Returns true iff a is later than b: */ diff --git a/fs/nfsd/xdr4cb.h b/fs/nfsd/xdr4cb.h index f4e29c0c701c..b06d0170d7c4 100644 --- a/fs/nfsd/xdr4cb.h +++ b/fs/nfsd/xdr4cb.h @@ -33,6 +33,18 @@ cb_sequence_dec_sz + \ op_dec_sz) =20 +#define NFS4_enc_cb_notify_sz (cb_compound_enc_hdr_sz + \ + cb_sequence_enc_sz + \ + 1 + enc_stateid_sz + \ + enc_nfs4_fh_sz + \ + 1 + \ + NOTIFY4_EVENT_QUEUE_SIZE * \ + (2 + (NFS4_OPAQUE_LIMIT >> 2))) + +#define NFS4_dec_cb_notify_sz (cb_compound_dec_hdr_sz + \ + cb_sequence_dec_sz + \ + op_dec_sz) + #define NFS4_enc_cb_notify_lock_sz (cb_compound_enc_hdr_sz + \ cb_sequence_enc_sz + \ 2 + 1 + \ --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 5C72239B949; Fri, 22 May 2026 12:29:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452964; cv=none; b=oCOTLXHRTo2TZoXHqRvxAGpqidYEsWeulsqkkXN6WemPfRbC5JorZu/FbcS59U4rY+s1NY8cA5Ff+2MeRHvKc5UetUbQ6KbgZXa38WF95+CL4Z3/eZnDX+gVIJCDD1cEH8qr2wDH/NNZF/goaxLKHrBu29hN3OwSt23D/rrICxs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452964; c=relaxed/simple; bh=Q9R3lexVfgStfNvJhEKl9Rwa8CS4i6Du2SQCwWtLH2o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HDj0Q73NiMKMama8EZBrXZuOX8PTVXj/5iTGHdE8sPJbxlduaqhx8fmnBMBsFCfRY3VF8Dx+3Uh817snZz1UgaLNZcqlUra9U9Hzd+dIHq/4og9tEW5LZr4j0In8IOqRp+KuoVPXZytr4BMFZwCgtS4xACmueuRRN2ELI5QzVuY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JYCaQiBe; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JYCaQiBe" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9057D1F00A3F; Fri, 22 May 2026 12:29:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452963; bh=vAsVyAMM+J0ncv0+jrvSeuHqV77JmQRnTLfS+JhnXVA=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=JYCaQiBeV1AP/v/bD1G4jlVFFCo35aQgAolMJvSymGHmmElxbWnCzrC9DQZRJF/+C nIwInCR0ACWo4lYlbnwD9j/HmKvofP0q/4fKAJS4cfp5ph92KGjkHAby8+LHZK3Ov8 fArtyKZ/yxfwPUdkCwsSInHEj2TqT0DgBgaZhGggBp10OVjGfad52LJ/Io7kCUGa/9 Fsl4+0Y9m1hVi5FMyVuD5Wt7NwxBRFUDwyZ+iUBZ/2/eBcNu+xEOiJ+U3UOma2pxOL WbPUBjg31H/sWHc3q6YJgfHQuV3qZvj1kfJcfezQzcg0P+gcUB+1Ii7KEo6JejtX6m BVumxeefwxx7w== From: Jeff Layton Date: Fri, 22 May 2026 08:28:57 -0400 Subject: [PATCH v4 08/21] nfsd: use RCU to protect fi_deleg_file Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-8-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7836; i=jlayton@kernel.org; h=from:subject:message-id; bh=Q9R3lexVfgStfNvJhEKl9Rwa8CS4i6Du2SQCwWtLH2o=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwPYE0G8u59cPwldvM5DKO8n5SWbxIF760cW 1cVXNNPN7mJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMDwAKCRAADmhBGVaC FSBYD/9iUfosgEKcLkXVBIk+Ab9aUqaUulnqu8Iv9mtjtZdcfBLNFbk8Qvaj0Epao5U9C702LMD iUP8lgThqj/3xYX8NumU16o6IF33Eqa7j3dQjsn4eHKa2pVA7+QB7z5q6PjtVeA9S0MiSpg25Aj HcJXkX/XEDs+s71ziqGeTNPxFMT2oz0MmHPqNqHGvoD4YgjiJN2VgmO2BSsYglzyZ/+y+nxbEw5 3tF/QWKIRB/zvAju+lulwpzE9GYKi5C71Wsi2FeTrVvOsFMxGv53pU9JDPe7KWSZISixnkVc/aj FA3tQnlCkdpWMfqsnOqHkiQ0AcUkumCDMARSq/zNjwcs0fcCcjwjDecCy1+hsXunqoMARCQMjlJ H9H9KTu/TSORGTz3nOiP5ePWhLSMOlj7R5umzYltsORB3O9bB/jR4Pa05ryjWPOosTqMIxz+qFH a1yzMzz1e7EhKHUiMO/VZV5eEQJCu0HdU6IBWUNSBthpJsSMcNK1WdSJGQb74H3kYPgmenRwa5V aFl/rHKEXvDsIBm66sw/gOUUgUngJ7mvpf6HKBGoKGET8UcVDYLNNKsigJXUtKC26DCoJTo4nGg 5xeiFQtUA5//LXqA6eG5L7wX44ie4cBjkfCGyrtfrDtEIgcB3aGGX7zvA7x2XiGJVBMY4Xxc5bd WT8E6dV3w9dEBdQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 fi_deleg_file can be NULLed by put_deleg_file() when fi_delegees drops to zero during delegation teardown (e.g. DELEGRETURN). Concurrent accesses from workqueue callbacks -- such as CB_NOTIFY -- can dereference a NULL pointer if they race with this teardown. Annotate fi_deleg_file with __rcu and convert all accessors to use proper RCU primitives: - rcu_assign_pointer() / RCU_INIT_POINTER() for stores - rcu_dereference_protected() for reads under fi_lock or where fi_delegees > 0 guarantees stability This prepares for a subsequent patch that will use rcu_read_lock + rcu_dereference + nfsd_file_get to safely acquire a reference from the CB_NOTIFY callback path without holding fi_lock. Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Jeff Layton --- fs/nfsd/nfs4layouts.c | 2 +- fs/nfsd/nfs4state.c | 40 ++++++++++++++++++++++++---------------- fs/nfsd/state.h | 2 +- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index e3984c90792e..9ed2e3d65062 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -248,7 +248,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state = *cstate, NFSPROC4_CLNT_CB_LAYOUT); =20 if (parent->sc_type =3D=3D SC_TYPE_DELEG) - ls->ls_file =3D nfsd_file_get(fp->fi_deleg_file); + ls->ls_file =3D nfsd_file_get(rcu_dereference_protected(fp->fi_deleg_fil= e, 1)); else ls->ls_file =3D find_any_file(fp); BUG_ON(!ls->ls_file); diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index beb6e95a1e4d..c7019cd07a91 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1212,7 +1212,9 @@ static void put_deleg_file(struct nfs4_file *fp) =20 spin_lock(&fp->fi_lock); if (--fp->fi_delegees =3D=3D 0) { - swap(nf, fp->fi_deleg_file); + nf =3D rcu_dereference_protected(fp->fi_deleg_file, + lockdep_is_held(&fp->fi_lock)); + rcu_assign_pointer(fp->fi_deleg_file, NULL); swap(rnf, fp->fi_rdeleg_file); } spin_unlock(&fp->fi_lock); @@ -1281,7 +1283,7 @@ static void nfsd_fsnotify_recalc_mask(struct nfsd_fil= e *nf) static void nfs4_unlock_deleg_lease(struct nfs4_delegation *dp) { struct nfs4_file *fp =3D dp->dl_stid.sc_file; - struct nfsd_file *nf =3D fp->fi_deleg_file; + struct nfsd_file *nf =3D rcu_dereference_protected(fp->fi_deleg_file, 1); =20 WARN_ON_ONCE(!fp->fi_delegees); =20 @@ -3175,7 +3177,8 @@ static int nfs4_show_deleg(struct seq_file *s, struct= nfs4_stid *st) /* XXX: lease time, whether it's being recalled. */ =20 spin_lock(&nf->fi_lock); - file =3D nf->fi_deleg_file; + file =3D rcu_dereference_protected(nf->fi_deleg_file, + lockdep_is_held(&nf->fi_lock)); if (file) { seq_puts(s, ", "); nfs4_show_superblock(s, file); @@ -4957,7 +4960,7 @@ static void nfsd4_file_init(const struct svc_fh *fh, = struct nfs4_file *fp) INIT_LIST_HEAD(&fp->fi_delegations); INIT_LIST_HEAD(&fp->fi_clnt_odstate); fh_copy_shallow(&fp->fi_fhandle, &fh->fh_handle); - fp->fi_deleg_file =3D NULL; + RCU_INIT_POINTER(fp->fi_deleg_file, NULL); fp->fi_rdeleg_file =3D NULL; fp->fi_had_conflict =3D false; fp->fi_share_deny =3D 0; @@ -6109,7 +6112,7 @@ static struct file_lease *nfs4_alloc_init_lease(struc= t nfs4_delegation *dp, u32 fl->c.flc_type =3D deleg_is_read(dp->dl_type) ? F_RDLCK : F_WRLCK; fl->c.flc_owner =3D (fl_owner_t)dp; fl->c.flc_pid =3D current->tgid; - fl->c.flc_file =3D dp->dl_stid.sc_file->fi_deleg_file->nf_file; + fl->c.flc_file =3D rcu_dereference_protected(dp->dl_stid.sc_file->fi_dele= g_file, 1)->nf_file; return fl; } =20 @@ -6117,7 +6120,7 @@ static int nfsd4_check_conflicting_opens(struct nfs4_= client *clp, struct nfs4_file *fp) { struct nfs4_ol_stateid *st; - struct file *f =3D fp->fi_deleg_file->nf_file; + struct file *f =3D rcu_dereference_protected(fp->fi_deleg_file, 1)->nf_fi= le; struct inode *ino =3D file_inode(f); int writes; =20 @@ -6194,7 +6197,7 @@ nfsd4_verify_deleg_dentry(struct nfsd4_open *open, st= ruct nfs4_file *fp, =20 exp_put(exp); dput(child); - if (child !=3D file_dentry(fp->fi_deleg_file->nf_file)) + if (child !=3D file_dentry(rcu_dereference_protected(fp->fi_deleg_file, 1= )->nf_file)) return -EAGAIN; =20 return 0; @@ -6300,8 +6303,9 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, status =3D -EAGAIN; else if (nfsd4_verify_setuid_write(open, nf)) status =3D -EAGAIN; - else if (!fp->fi_deleg_file) { - fp->fi_deleg_file =3D nf; + else if (!rcu_dereference_protected(fp->fi_deleg_file, + lockdep_is_held(&fp->fi_lock))) { + rcu_assign_pointer(fp->fi_deleg_file, nf); /* increment early to prevent fi_deleg_file from being * cleared */ fp->fi_delegees =3D 1; @@ -6326,7 +6330,7 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, if (!fl) goto out_clnt_odstate; =20 - status =3D kernel_setlease(fp->fi_deleg_file->nf_file, + status =3D kernel_setlease(rcu_dereference_protected(fp->fi_deleg_file, 1= )->nf_file, fl->c.flc_type, &fl, NULL); if (fl) locks_free_lease(fl); @@ -6347,7 +6351,7 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, * Now that the deleg is set, check again to ensure that nothing * raced in and changed the mode while we weren't looking. */ - status =3D nfsd4_verify_setuid_write(open, fp->fi_deleg_file); + status =3D nfsd4_verify_setuid_write(open, rcu_dereference_protected(fp->= fi_deleg_file, 1)); if (status) goto out_unlock; =20 @@ -6368,7 +6372,8 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, =20 return dp; out_unlock: - kernel_setlease(fp->fi_deleg_file->nf_file, F_UNLCK, NULL, (void **)&dp); + kernel_setlease(rcu_dereference_protected(fp->fi_deleg_file, 1)->nf_file, + F_UNLCK, NULL, (void **)&dp); out_clnt_odstate: put_clnt_odstate(dp->dl_clnt_odstate); nfs4_put_stid(&dp->dl_stid); @@ -6525,8 +6530,9 @@ nfs4_open_delegation(struct svc_rqst *rqstp, struct n= fsd4_open *open, memcpy(&open->op_delegate_stateid, &dp->dl_stid.sc_stateid, sizeof(dp->dl= _stid.sc_stateid)); =20 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) { - struct file *f =3D dp->dl_stid.sc_file->fi_deleg_file->nf_file; + struct file *f; =20 + f =3D rcu_dereference_protected(dp->dl_stid.sc_file->fi_deleg_file, 1)->= nf_file; if (!nfsd4_add_rdaccess_to_wrdeleg(rqstp, open, fh, stp) || !nfs4_delegation_stat(dp, currentfh, &stat)) { nfs4_put_stid(&dp->dl_stid); @@ -9668,8 +9674,9 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstat= e, /* existing delegation? */ if (nfs4_delegation_exists(clp, fp)) { status =3D -EAGAIN; - } else if (!fp->fi_deleg_file) { - fp->fi_deleg_file =3D nfsd_file_get(nf); + } else if (!rcu_dereference_protected(fp->fi_deleg_file, + lockdep_is_held(&fp->fi_lock))) { + rcu_assign_pointer(fp->fi_deleg_file, nfsd_file_get(nf)); fp->fi_delegees =3D 1; } else { ++fp->fi_delegees; @@ -9721,7 +9728,8 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstat= e, } =20 /* Something failed. Drop the lease and clean up the stid */ - kernel_setlease(fp->fi_deleg_file->nf_file, F_UNLCK, NULL, (void **)&dp); + kernel_setlease(rcu_dereference_protected(fp->fi_deleg_file, 1)->nf_file, + F_UNLCK, NULL, (void **)&dp); out_put_stid: nfs4_put_stid(&dp->dl_stid); out_delegees: diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 790282781243..9c6e2e7abc82 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -698,7 +698,7 @@ struct nfs4_file { */ atomic_t fi_access[2]; u32 fi_share_deny; - struct nfsd_file *fi_deleg_file; + struct nfsd_file __rcu *fi_deleg_file; struct nfsd_file *fi_rdeleg_file; int fi_delegees; struct knfsd_fh fi_fhandle; --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 E9C3B39D3D4; Fri, 22 May 2026 12:29:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452966; cv=none; b=PLk227RVAI3WJ6lhssNSm/QZX2etGAN7Sosw4TS/Gs4wj7FmzhQbiqOP38meMkQGKR6bCZKoTWArsCe1Fijx7S+pmoWTXM61mH9GMv0B6ldWySbI4lo6BBuvvjbkoqowOPnx0zPwwPn+iGpx/8MgbuVmJtlX2sCRFM+6pnYWcW4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452966; c=relaxed/simple; bh=T6bm4N+iUMTTYW/+h5LeT3X0sv+drarf73qwr1XDSuU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rfqel1DPM45Qi4oTef2Kd+eOMyM7qTP1zdBDCpBuzBsW7r8/w34RVHY2k0mUb9WK240Cc+sGm2MxFqk7yH/n3jYi9t3qlg16sy7u3nUDFfLLs6bQUY/DGg8meqZbVsXjU5qLJpvV8m6vLb3vouggDLlr/79akZFo9Y0IirPhvR8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e2mYp0XX; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="e2mYp0XX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4706D1F00A3D; Fri, 22 May 2026 12:29:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452964; bh=aNqw8zPmMjOsXjdzzKZBzh0tC8+Deus+16AVrK2PeKY=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=e2mYp0XXZbLgaTmUoJfPsHsHlW+/PxID0x138It4E2KvsxM3HBn7ljriNnvq6Ruke bz1rQqBwtke/QCChNVmOs5ggB028XL2p5xxSTJWryBD0DWHNqnydvRTOjOym6FA2Yg 1EtLjrgioyo21Kq6WYZg3x6GQY6KpgY9JTbjPSqCdVuDYe2GQGJckknCHymAClpJAH 7Xxs9gp2IGRvzFhWDzbnky3kys5WKotnWIuVW8vnnHUWvQ8Xxl0ERAgkfn5bFCeswX /aRQwFQYhMG4l4fv+hlKNIl88CXHaSE8gbzl0esY6COgZ0/gsU+V9PpTcJ3kAyxTyH yzIBRimZCsQPA== From: Jeff Layton Date: Fri, 22 May 2026 08:28:58 -0400 Subject: [PATCH v4 09/21] nfsd: add data structures for handling CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-9-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9059; i=jlayton@kernel.org; h=from:subject:message-id; bh=T6bm4N+iUMTTYW/+h5LeT3X0sv+drarf73qwr1XDSuU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwPQlKfjP/SjjZmJhyQ11ehX+oZ1fBITyM7f AdXrccE3paJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMDwAKCRAADmhBGVaC FYgAEAC6dVpE2/Sf633tHPaU6FOi2JRTXbx7El5yNbFJjr6v8Qpk1PvmTIUDQonTw6sYjskXqlD T8WhbgARk1wOEZVdl8/PC2MKToaWDzkFOjj36xYsffpOjzp73R0LfMox9HVV29YcqmjzyrQoxwv GGYf62xSvF9tn0FjO/SYkhCCkiVmq/sUJsGsNoPX15VRjSmDIYZINi4CBvH1rIBiS2wUy5eXIBZ rwNv9UXfVBvibp+OFtnkEZCugXX7KwkJH14KEcuDX73Sw3k5CrYSSo1dclkOO445EgaoKiRiEvY L4k1Rmtuay4sHRfMZVzwiisEaIEDb10uVUjkxOwZKNKyzLniZcVIgt1Al7OVo5sCCsio7FOM43/ e9Ixkr4+DGful0hnJ2hgxHoWOjZ3x7PCzYsLf1rmN7abctG3I7XHYPhggPY2BABT+0nxpHjd2zq 8RD8Xkavkbzuy1UYZiOYEV0+SzP8GuqhaLXxlfA8KMBMCuFvQfqlDkWsIdLodFUAMSHIMQkxSfX x+ltNB97TWFOSoaugkCdsa4r2D46i2XGiUioz4ChC6n5khOJu2rqkFTSMaqjqzjmncVHff2mXOi lqSXQsWozwozuw7TWnuYOjmOLovFkK5s+wwNzy56fZ6is9lZYKGVHZohCqAkmhpSgN0CuUta3/7 r5Q7sdIxIZemEqw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add the data structures, allocation helpers, and callback operations needed for directory delegation CB_NOTIFY support: - struct nfsd_notify_event: carries fsnotify events for CB_NOTIFY - struct nfsd4_cb_notify: per-delegation state for notification handling - Union dl_cb_fattr with dl_cb_notify in nfs4_delegation since a delegation is either a regular file delegation or a directory delegation, never both Refactor alloc_init_deleg() into a common __alloc_init_deleg() base with a pluggable sc_free callback, and add alloc_init_dir_deleg() which allocates the page array and notify4 buffer needed for CB_NOTIFY encoding. Add skeleton nfsd4_cb_notify_ops with done/release handlers that will be filled in when the notification path is wired up. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 118 +++++++++++++++++++++++++++++++++++++++++++++---= ---- fs/nfsd/state.h | 46 +++++++++++++++++++- 2 files changed, 148 insertions(+), 16 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c7019cd07a91..8a4fb41b84c9 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -126,6 +126,7 @@ static void free_session(struct nfsd4_session *); static const struct nfsd4_callback_ops nfsd4_cb_recall_ops; static const struct nfsd4_callback_ops nfsd4_cb_notify_lock_ops; static const struct nfsd4_callback_ops nfsd4_cb_getattr_ops; +static const struct nfsd4_callback_ops nfsd4_cb_notify_ops; =20 static struct workqueue_struct *laundry_wq; =20 @@ -1123,29 +1124,31 @@ static void block_delegations(struct knfsd_fh *fh) } =20 static struct nfs4_delegation * -alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, - struct nfs4_clnt_odstate *odstate, u32 dl_type) +__alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, + struct nfs4_clnt_odstate *odstate, u32 dl_type, + void (*sc_free)(struct nfs4_stid *)) { struct nfs4_delegation *dp; struct nfs4_stid *stid; long n; =20 - dprintk("NFSD alloc_init_deleg\n"); + if (delegation_blocked(&fp->fi_fhandle)) + return NULL; + n =3D atomic_long_inc_return(&num_delegations); if (n < 0 || n > max_delegations) goto out_dec; - if (delegation_blocked(&fp->fi_fhandle)) - goto out_dec; - stid =3D nfs4_alloc_stid(clp, deleg_slab, nfs4_free_deleg); + + stid =3D nfs4_alloc_stid(clp, deleg_slab, sc_free); if (stid =3D=3D NULL) goto out_dec; - dp =3D delegstateid(stid); =20 /* * delegation seqid's are never incremented. The 4.1 special * meaning of seqid 0 isn't meaningful, really, but let's avoid - * 0 anyway just for consistency and use 1: + * 0 anyway just for consistency and use 1. */ + dp =3D delegstateid(stid); dp->dl_stid.sc_stateid.si_generation =3D 1; INIT_LIST_HEAD(&dp->dl_perfile); INIT_LIST_HEAD(&dp->dl_perclnt); @@ -1155,19 +1158,76 @@ alloc_init_deleg(struct nfs4_client *clp, struct nf= s4_file *fp, dp->dl_type =3D dl_type; dp->dl_retries =3D 1; dp->dl_recalled =3D false; - nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client, - &nfsd4_cb_recall_ops, NFSPROC4_CLNT_CB_RECALL); - nfsd4_init_cb(&dp->dl_cb_fattr.ncf_getattr, dp->dl_stid.sc_client, - &nfsd4_cb_getattr_ops, NFSPROC4_CLNT_CB_GETATTR); - dp->dl_cb_fattr.ncf_file_modified =3D false; get_nfs4_file(fp); dp->dl_stid.sc_file =3D fp; + nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client, + &nfsd4_cb_recall_ops, NFSPROC4_CLNT_CB_RECALL); return dp; out_dec: atomic_long_dec(&num_delegations); return NULL; } =20 +static struct nfs4_delegation * +alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, + struct nfs4_clnt_odstate *odstate, u32 dl_type) +{ + struct nfs4_delegation *dp; + + dp =3D __alloc_init_deleg(clp, fp, odstate, dl_type, nfs4_free_deleg); + if (!dp) + return NULL; + + nfsd4_init_cb(&dp->dl_cb_fattr.ncf_getattr, dp->dl_stid.sc_client, + &nfsd4_cb_getattr_ops, NFSPROC4_CLNT_CB_GETATTR); + dp->dl_cb_fattr.ncf_file_modified =3D false; + return dp; +} + +static void nfs4_free_dir_deleg(struct nfs4_stid *stid) +{ + struct nfs4_delegation *dp =3D delegstateid(stid); + struct nfsd4_cb_notify *ncn =3D &dp->dl_cb_notify; + int i; + + for (i =3D 0; i < ncn->ncn_evt_cnt; ++i) + nfsd_notify_event_put(ncn->ncn_evt[i]); + kfree(ncn->ncn_nf); + release_pages(ncn->ncn_pages, NOTIFY4_PAGE_ARRAY_SIZE); + nfs4_free_deleg(stid); +} + +static struct nfs4_delegation * +alloc_init_dir_deleg(struct nfs4_client *clp, struct nfs4_file *fp) +{ + struct nfs4_delegation *dp; + struct nfsd4_cb_notify *ncn; + int npages; + + dp =3D __alloc_init_deleg(clp, fp, NULL, NFS4_OPEN_DELEGATE_READ, nfs4_fr= ee_dir_deleg); + if (!dp) + return NULL; + + ncn =3D &dp->dl_cb_notify; + + npages =3D alloc_pages_bulk(GFP_KERNEL, NOTIFY4_PAGE_ARRAY_SIZE, ncn->ncn= _pages); + if (npages !=3D NOTIFY4_PAGE_ARRAY_SIZE) { + release_pages(ncn->ncn_pages, npages); + nfs4_free_deleg(&dp->dl_stid); + return NULL; + } + + ncn->ncn_nf =3D kcalloc(NOTIFY4_EVENT_QUEUE_SIZE, sizeof(*ncn->ncn_nf), G= FP_KERNEL); + if (!ncn->ncn_nf) { + nfs4_put_stid(&dp->dl_stid); + return NULL; + } + spin_lock_init(&ncn->ncn_lock); + nfsd4_init_cb(&ncn->ncn_cb, dp->dl_stid.sc_client, + &nfsd4_cb_notify_ops, NFSPROC4_CLNT_CB_NOTIFY); + return dp; +} + void nfs4_put_stid(struct nfs4_stid *s) { @@ -3397,6 +3457,30 @@ nfsd4_cb_getattr_release(struct nfsd4_callback *cb) nfs4_put_stid(&dp->dl_stid); } =20 +static int +nfsd4_cb_notify_done(struct nfsd4_callback *cb, + struct rpc_task *task) +{ + switch (task->tk_status) { + case -NFS4ERR_DELAY: + rpc_delay(task, 2 * HZ); + return 0; + default: + return 1; + } +} + +static void +nfsd4_cb_notify_release(struct nfsd4_callback *cb) +{ + struct nfsd4_cb_notify *ncn =3D + container_of(cb, struct nfsd4_cb_notify, ncn_cb); + struct nfs4_delegation *dp =3D + container_of(ncn, struct nfs4_delegation, dl_cb_notify); + + nfs4_put_stid(&dp->dl_stid); +} + static const struct nfsd4_callback_ops nfsd4_cb_recall_any_ops =3D { .done =3D nfsd4_cb_recall_any_done, .release =3D nfsd4_cb_recall_any_release, @@ -3409,6 +3493,12 @@ static const struct nfsd4_callback_ops nfsd4_cb_geta= ttr_ops =3D { .opcode =3D OP_CB_GETATTR, }; =20 +static const struct nfsd4_callback_ops nfsd4_cb_notify_ops =3D { + .done =3D nfsd4_cb_notify_done, + .release =3D nfsd4_cb_notify_release, + .opcode =3D OP_CB_NOTIFY, +}; + static void nfs4_cb_getattr(struct nfs4_cb_fattr *ncf) { struct nfs4_delegation *dp =3D @@ -9691,7 +9781,7 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstat= e, =20 /* Try to set up the lease */ status =3D -ENOMEM; - dp =3D alloc_init_deleg(clp, fp, NULL, NFS4_OPEN_DELEGATE_READ); + dp =3D alloc_init_dir_deleg(clp, fp); if (!dp) goto out_delegees; if (cstate->current_fh.fh_export) diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 9c6e2e7abc82..505fabf8f1bf 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -197,6 +197,44 @@ struct nfs4_cb_fattr { #define NOTIFY4_EVENT_QUEUE_SIZE 3 #define NOTIFY4_PAGE_ARRAY_SIZE 1 =20 +struct nfsd_notify_event { + refcount_t ne_ref; // refcount + u32 ne_mask; // FS_* mask from fsnotify callback + struct dentry *ne_dentry; // dentry reference to target + u32 ne_namelen; // length of ne_name + char ne_name[]; // name of dentry being changed +}; + +static inline struct nfsd_notify_event *nfsd_notify_event_get(struct nfsd_= notify_event *ne) +{ + refcount_inc(&ne->ne_ref); + return ne; +} + +static inline void nfsd_notify_event_put(struct nfsd_notify_event *ne) +{ + if (refcount_dec_and_test(&ne->ne_ref)) { + dput(ne->ne_dentry); + kfree(ne); + } +} + +/* + * Represents a directory delegation. The callback is for handling CB_NOTI= FYs. + * As notifications from fsnotify come in, allocate a new event, take the = ncn_lock, + * and add it to the ncn_evt queue. The CB_NOTIFY prepare handler will tak= e the + * lock, clean out the list and process it. + */ +struct nfsd4_cb_notify { + spinlock_t ncn_lock; // protects the evt queue and count + int ncn_evt_cnt; // count of events in ncn_evt + int ncn_nf_cnt; // count of valid entries in ncn_nf + struct nfsd_notify_event *ncn_evt[NOTIFY4_EVENT_QUEUE_SIZE]; // list of e= vents + struct page *ncn_pages[NOTIFY4_PAGE_ARRAY_SIZE]; // for encoding + struct notify4 *ncn_nf; // array of notify4's to be sent + struct nfsd4_callback ncn_cb; // notify4 callback +}; + /* * Represents a delegation stateid. The nfs4_client holds references to th= ese * and they are put when it is being destroyed or when the delegation is @@ -233,8 +271,12 @@ struct nfs4_delegation { bool dl_written; bool dl_setattr; =20 - /* for CB_GETATTR */ - struct nfs4_cb_fattr dl_cb_fattr; + union { + /* for CB_GETATTR */ + struct nfs4_cb_fattr dl_cb_fattr; + /* for CB_NOTIFY */ + struct nfsd4_cb_notify dl_cb_notify; + }; =20 /* For delegated timestamps */ struct timespec64 dl_atime; --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 C69E739F183; Fri, 22 May 2026 12:29:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452969; cv=none; b=e83MgwEhj0mw5XJmFx1PE8RJsJyqa4hZGwgCDWmrBXVPUkNj68q0et+BLn3ptYewcnlbRO0F+SfkMOzWnriiAcJfPZZyqKpGSiSHyqmAgXDUjeGcaL7EFHJ/eivD+iCMSn7J3NvxwUbknw0p2Wi3r5SfMPM6iyo7jMo+PaAyka4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452969; c=relaxed/simple; bh=Uu4tDkKoytdRq57XY7pijXjWvigWHLAZI1AxVhlmhRs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dHNg1hjaZUMJjIkYPOrQ4aA7BsKHtyrjW38ji7Vm5wravIIFdJR88QlkFDWpqYVFTkjOMpKRW4V0GzSP6j4GxC865uf4NQVPjHJsyCUNgB5JT2/3nQegbBF96SgiFOQhUObWh/fpUjVI7mQB/mZzQ+wefn6cjvvPSH5nVkZQrY4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=I+FUHKKt; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="I+FUHKKt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F15C71F000E9; Fri, 22 May 2026 12:29:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452966; bh=hkizLCm3QMsM0IeJ8aY/PsvxeOtNLlUq74YGgXZ0zxs=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=I+FUHKKtzwNsFfAveq+ddqQt9VCnQTfONq4qEGbAE8rVcEGklJ2PD5XI2eJr+sUx0 va8RuTGOEWGoM8wYOzBWbsZPD4jK0/fj7I129FKOFH5lll/QxL0hRmO/DpUxuKYXsI nIjDVHATH2YBYOA817MBEKKXJjPfvpu+JSnPwxN+ItoXJVa9bfTtojFG5BKt4oqiKA mv7BD+BIg41JRkbKxTtsb8RicKwpT4A6p6Q2VijGiBAuUwqRw6HsdRwd8GcqrlMoPs dCMKjnYsSRfe/xsnqdzIbVomd/Q82ZAef3LIgmyDi/1LZlcidjhjaN8s7NeICNwRXN Nm6sUD0u3BdhA== From: Jeff Layton Date: Fri, 22 May 2026 08:28:59 -0400 Subject: [PATCH v4 10/21] nfsd: add notification handlers for dir events Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-10-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=23201; i=jlayton@kernel.org; h=from:subject:message-id; bh=Uu4tDkKoytdRq57XY7pijXjWvigWHLAZI1AxVhlmhRs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwPeBLRicHcM4m2E0x9hhBMD4WOzsUsvXWht 423jEstoGSJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMDwAKCRAADmhBGVaC FRxoD/9fDO0n+8uiHxg6Sf1anwYjHCCbdwitISwAatRJ1P4niNGPR5L6o/defzOfFUiSVbA/SRd 65eY18uEbJLfilpxn9CAnchputR8QHYuO2xvt8E3td3gUygPl+35tVB7/4WrI2Ek42omPXxveW8 GdUGHlDaJZYeBxZ3z3w8DmzdlxVqjLim2YZccetOe5cX9F1gTmj8iA5VbOOf9AA4NxvkYWzTVgP HOgjfxPLiSNCRjvSPZQWJ598zmL6u9OrdGEFt4rDLkst0wmjmQ/0bt1vY20jaiPHihAHveGF/cT bN/VMRB/4i3sXmHhh0CL3LjLhVOnEaEODX77FEwcHSEvQ5wI70/5H5lGvLV4hUnSQtT1B7y99Fa menA52GlK+YJuD63b2T7AInBqmfJkS77zZd9o+BECYr0WZ4jIJrFDPI0NWDNF3puzo/DFkLCvDv 4PXaM+oge/EUBZNHCCfwuvys4Vtp96s3dh1/Pygk5PK8AXioy4A6tFqk4kbrZSyQ7UC3EKBbZGC 9AFhVxBkrzsck6gdUPMmtdddtZpPJLkHYyJ/5GnGaW4oKw9jZkJg2IIQpnnLivX7y9myIVWmuRk DBpmPTCq8TDfV0c0esVRL4/eUP/5J59oy4U2FJflztEFUfqvwvXKiGlMpdcC3mC69w0ndYX5La+ 02LV6XWXui/yWBQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add the necessary parts to accept a fsnotify callback for directory change event and create a CB_NOTIFY request for it. When a dir nfsd_file is created set a handle_event callback to handle the notification. Use that to allocate a nfsd_notify_event object and then hand off a reference to each delegation's CB_NOTIFY. If anything fails along the way, recall any affected delegations. Signed-off-by: Jeff Layton --- fs/nfsd/filecache.c | 70 ++++++++++--- fs/nfsd/nfs4callback.c | 19 +++- fs/nfsd/nfs4state.c | 268 +++++++++++++++++++++++++++++++++++++++++++++= ---- fs/nfsd/nfs4xdr.c | 121 ++++++++++++++++++++++ fs/nfsd/state.h | 4 + fs/nfsd/xdr4.h | 3 + 6 files changed, 443 insertions(+), 42 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 24511c3208db..be8f6d8a3ba0 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -72,6 +72,7 @@ static struct kmem_cache *nfsd_file_mark_slab; static struct list_lru nfsd_file_lru; static unsigned long nfsd_file_flags; static struct fsnotify_group *nfsd_file_fsnotify_group; +static struct fsnotify_group *nfsd_dir_fsnotify_group; static struct delayed_work nfsd_filecache_laundrette; static struct rhltable nfsd_file_rhltable ____cacheline_aligned_in_smp; @@ -147,7 +148,7 @@ static void nfsd_file_mark_put(struct nfsd_file_mark *nfm) { if (refcount_dec_and_test(&nfm->nfm_ref)) { - fsnotify_destroy_mark(&nfm->nfm_mark, nfsd_file_fsnotify_group); + fsnotify_destroy_mark(&nfm->nfm_mark, nfm->nfm_mark.group); fsnotify_put_mark(&nfm->nfm_mark); } } @@ -155,35 +156,37 @@ nfsd_file_mark_put(struct nfsd_file_mark *nfm) static struct nfsd_file_mark * nfsd_file_mark_find_or_create(struct inode *inode) { - int err; - struct fsnotify_mark *mark; struct nfsd_file_mark *nfm =3D NULL, *new; + struct fsnotify_group *group; + struct fsnotify_mark *mark; + int err; + + group =3D S_ISDIR(inode->i_mode) ? nfsd_dir_fsnotify_group : nfsd_file_fs= notify_group; =20 do { - fsnotify_group_lock(nfsd_file_fsnotify_group); - mark =3D fsnotify_find_inode_mark(inode, - nfsd_file_fsnotify_group); + fsnotify_group_lock(group); + mark =3D fsnotify_find_inode_mark(inode, group); if (mark) { nfm =3D nfsd_file_mark_get(container_of(mark, struct nfsd_file_mark, nfm_mark)); - fsnotify_group_unlock(nfsd_file_fsnotify_group); + fsnotify_group_unlock(group); if (nfm) { fsnotify_put_mark(mark); break; } /* Avoid soft lockup race with nfsd_file_mark_put() */ - fsnotify_destroy_mark(mark, nfsd_file_fsnotify_group); + fsnotify_destroy_mark(mark, group); fsnotify_put_mark(mark); } else { - fsnotify_group_unlock(nfsd_file_fsnotify_group); + fsnotify_group_unlock(group); } =20 /* allocate a new nfm */ new =3D kmem_cache_alloc(nfsd_file_mark_slab, GFP_KERNEL); if (!new) return NULL; - fsnotify_init_mark(&new->nfm_mark, nfsd_file_fsnotify_group); + fsnotify_init_mark(&new->nfm_mark, group); new->nfm_mark.mask =3D FS_ATTRIB|FS_DELETE_SELF; refcount_set(&new->nfm_ref, 1); =20 @@ -812,12 +815,36 @@ nfsd_file_fsnotify_handle_event(struct fsnotify_mark = *mark, u32 mask, return 0; } =20 +#ifdef CONFIG_NFSD_V4 +static int +nfsd_dir_fsnotify_handle_event(struct fsnotify_group *group, u32 mask, + const void *data, int data_type, struct inode *dir, + const struct qstr *name, u32 cookie, + struct fsnotify_iter_info *iter_info) +{ + return nfsd_handle_dir_event(mask, dir, data, data_type, name); +} +#else +static int +nfsd_dir_fsnotify_handle_event(struct fsnotify_group *group, u32 mask, + const void *data, int data_type, struct inode *dir, + const struct qstr *name, u32 cookie, + struct fsnotify_iter_info *iter_info) +{ + return 0; +} +#endif =20 static const struct fsnotify_ops nfsd_file_fsnotify_ops =3D { .handle_inode_event =3D nfsd_file_fsnotify_handle_event, .free_mark =3D nfsd_file_mark_free, }; =20 +static const struct fsnotify_ops nfsd_dir_fsnotify_ops =3D { + .handle_event =3D nfsd_dir_fsnotify_handle_event, + .free_mark =3D nfsd_file_mark_free, +}; + int nfsd_file_cache_init(void) { @@ -869,8 +896,7 @@ nfsd_file_cache_init(void) goto out_shrinker; } =20 - nfsd_file_fsnotify_group =3D fsnotify_alloc_group(&nfsd_file_fsnotify_ops, - 0); + nfsd_file_fsnotify_group =3D fsnotify_alloc_group(&nfsd_file_fsnotify_ops= , 0); if (IS_ERR(nfsd_file_fsnotify_group)) { pr_err("nfsd: unable to create fsnotify group: %ld\n", PTR_ERR(nfsd_file_fsnotify_group)); @@ -879,11 +905,23 @@ nfsd_file_cache_init(void) goto out_notifier; } =20 + nfsd_dir_fsnotify_group =3D fsnotify_alloc_group(&nfsd_dir_fsnotify_ops, = 0); + if (IS_ERR(nfsd_dir_fsnotify_group)) { + pr_err("nfsd: unable to create fsnotify group: %ld\n", + PTR_ERR(nfsd_dir_fsnotify_group)); + ret =3D PTR_ERR(nfsd_dir_fsnotify_group); + nfsd_dir_fsnotify_group =3D NULL; + goto out_notify_group; + } + INIT_DELAYED_WORK(&nfsd_filecache_laundrette, nfsd_file_gc_worker); out: if (ret) clear_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags); return ret; +out_notify_group: + fsnotify_put_group(nfsd_file_fsnotify_group); + nfsd_file_fsnotify_group =3D NULL; out_notifier: lease_unregister_notifier(&nfsd_file_lease_notifier); out_shrinker: @@ -1019,6 +1057,8 @@ nfsd_file_cache_shutdown(void) rcu_barrier(); fsnotify_put_group(nfsd_file_fsnotify_group); nfsd_file_fsnotify_group =3D NULL; + fsnotify_put_group(nfsd_dir_fsnotify_group); + nfsd_dir_fsnotify_group =3D NULL; kmem_cache_destroy(nfsd_file_slab); nfsd_file_slab =3D NULL; fsnotify_wait_marks_destroyed(); @@ -1223,10 +1263,8 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct = net *net, open_file: trace_nfsd_file_alloc(nf); =20 - if (type =3D=3D S_IFREG) - nf->nf_mark =3D nfsd_file_mark_find_or_create(inode); - - if (type !=3D S_IFREG || nf->nf_mark) { + nf->nf_mark =3D nfsd_file_mark_find_or_create(inode); + if (nf->nf_mark) { if (file) { get_file(file); nf->nf_file =3D file; diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index ea3e7deb06fa..1964a213f80e 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -870,21 +870,30 @@ static void nfs4_xdr_enc_cb_notify(struct rpc_rqst *r= eq, const void *data) { const struct nfsd4_callback *cb =3D data; + struct nfsd4_cb_notify *ncn =3D container_of(cb, struct nfsd4_cb_notify, = ncn_cb); + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); struct nfs4_cb_compound_hdr hdr =3D { .ident =3D 0, .minorversion =3D cb->cb_clp->cl_minorversion, }; - struct CB_NOTIFY4args args =3D { }; + struct CB_NOTIFY4args args; + __be32 *p; =20 WARN_ON_ONCE(hdr.minorversion =3D=3D 0); =20 encode_cb_compound4args(xdr, &hdr); encode_cb_sequence4args(xdr, cb, &hdr); =20 - /* - * FIXME: get stateid and fh from delegation. Inline the cna_changes - * buffer, and zero it. - */ + p =3D xdr_reserve_space(xdr, 4); + *p =3D cpu_to_be32(OP_CB_NOTIFY); + + args.cna_stateid.seqid =3D dp->dl_stid.sc_stateid.si_generation; + memcpy(&args.cna_stateid.other, &dp->dl_stid.sc_stateid.si_opaque, + ARRAY_SIZE(args.cna_stateid.other)); + args.cna_fh.len =3D dp->dl_stid.sc_file->fi_fhandle.fh_size; + args.cna_fh.data =3D dp->dl_stid.sc_file->fi_fhandle.fh_raw; + args.cna_changes.count =3D ncn->ncn_nf_cnt; + args.cna_changes.element =3D ncn->ncn_nf; WARN_ON_ONCE(!xdrgen_encode_CB_NOTIFY4args(xdr, &args)); =20 hdr.nops++; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 8a4fb41b84c9..3afde2e91efe 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -55,6 +55,7 @@ #include "netns.h" #include "pnfs.h" #include "filecache.h" +#include "nfs4xdr_gen.h" #include "trace.h" =20 #define NFSDDBG_FACILITY NFSDDBG_PROC @@ -3457,19 +3458,131 @@ nfsd4_cb_getattr_release(struct nfsd4_callback *cb) nfs4_put_stid(&dp->dl_stid); } =20 +static void nfsd_break_one_deleg(struct nfs4_delegation *dp) +{ + bool queued; + + if (test_and_set_bit(NFSD4_CALLBACK_RUNNING, &dp->dl_recall.cb_flags)) + return; + + /* + * We're assuming the state code never drops its reference + * without first removing the lease. Since we're in this lease + * callback (and since the lease code is serialized by the + * flc_lock) we know the server hasn't removed the lease yet, and + * we know it's safe to take a reference. + */ + refcount_inc(&dp->dl_stid.sc_count); + queued =3D nfsd4_run_cb(&dp->dl_recall); + WARN_ON_ONCE(!queued); + if (!queued) + refcount_dec(&dp->dl_stid.sc_count); +} + +static bool +nfsd4_cb_notify_prepare(struct nfsd4_callback *cb) +{ + struct nfsd4_cb_notify *ncn =3D container_of(cb, struct nfsd4_cb_notify, = ncn_cb); + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); + struct nfsd_notify_event *events[NOTIFY4_EVENT_QUEUE_SIZE]; + struct xdr_buf xdr =3D { .buflen =3D PAGE_SIZE * NOTIFY4_PAGE_ARRAY_SIZE, + .pages =3D ncn->ncn_pages }; + struct xdr_stream stream; + struct nfsd_file *nf; + int count, i; + bool error =3D false; + + xdr_init_encode_pages(&stream, &xdr); + + spin_lock(&ncn->ncn_lock); + count =3D ncn->ncn_evt_cnt; + + /* spurious queueing? */ + if (count =3D=3D 0) { + spin_unlock(&ncn->ncn_lock); + return false; + } + + /* we can't keep up! */ + if (count > NOTIFY4_EVENT_QUEUE_SIZE) { + spin_unlock(&ncn->ncn_lock); + goto out_recall; + } + + memcpy(events, ncn->ncn_evt, sizeof(*events) * count); + ncn->ncn_evt_cnt =3D 0; + spin_unlock(&ncn->ncn_lock); + + rcu_read_lock(); + nf =3D nfsd_file_get(rcu_dereference(dp->dl_stid.sc_file->fi_deleg_file)); + rcu_read_unlock(); + if (!nf) { + for (i =3D 0; i < count; ++i) + nfsd_notify_event_put(events[i]); + goto out_recall; + } + + for (i =3D 0; i < count; ++i) { + struct nfsd_notify_event *nne =3D events[i]; + + if (!error) { + u32 *maskp =3D (u32 *)xdr_reserve_space(&stream, sizeof(*maskp)); + u8 *p; + + if (!maskp) { + error =3D true; + goto put_event; + } + + p =3D nfsd4_encode_notify_event(&stream, nne, dp, nf, maskp); + if (!p) { + pr_notice("Could not generate CB_NOTIFY from fsnotify mask 0x%x\n", + nne->ne_mask); + error =3D true; + goto put_event; + } + + ncn->ncn_nf[i].notify_mask.count =3D 1; + ncn->ncn_nf[i].notify_mask.element =3D maskp; + ncn->ncn_nf[i].notify_vals.data =3D p; + ncn->ncn_nf[i].notify_vals.len =3D (u8 *)stream.p - p; + } +put_event: + nfsd_notify_event_put(nne); + } + if (!error) { + ncn->ncn_nf_cnt =3D count; + nfsd_file_put(nf); + return true; + } + nfsd_file_put(nf); +out_recall: + nfsd_break_one_deleg(dp); + return false; +} + static int nfsd4_cb_notify_done(struct nfsd4_callback *cb, struct rpc_task *task) { + struct nfsd4_cb_notify *ncn =3D container_of(cb, struct nfsd4_cb_notify, = ncn_cb); + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); + switch (task->tk_status) { case -NFS4ERR_DELAY: rpc_delay(task, 2 * HZ); return 0; default: + /* For any other hard error, recall the deleg */ + nfsd_break_one_deleg(dp); + fallthrough; + case 0: return 1; } } =20 +static void nfsd4_run_cb_notify(struct nfsd4_cb_notify *ncn); + static void nfsd4_cb_notify_release(struct nfsd4_callback *cb) { @@ -3478,6 +3591,9 @@ nfsd4_cb_notify_release(struct nfsd4_callback *cb) struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, dl_cb_notify); =20 + /* Drain events that arrived while this callback was in flight */ + if (ncn->ncn_evt_cnt > 0) + nfsd4_run_cb_notify(ncn); nfs4_put_stid(&dp->dl_stid); } =20 @@ -3494,6 +3610,7 @@ static const struct nfsd4_callback_ops nfsd4_cb_getat= tr_ops =3D { }; =20 static const struct nfsd4_callback_ops nfsd4_cb_notify_ops =3D { + .prepare =3D nfsd4_cb_notify_prepare, .done =3D nfsd4_cb_notify_done, .release =3D nfsd4_cb_notify_release, .opcode =3D OP_CB_NOTIFY, @@ -5726,27 +5843,6 @@ static const struct nfsd4_callback_ops nfsd4_cb_reca= ll_ops =3D { .opcode =3D OP_CB_RECALL, }; =20 -static void nfsd_break_one_deleg(struct nfs4_delegation *dp) -{ - bool queued; - - if (test_and_set_bit(NFSD4_CALLBACK_RUNNING, &dp->dl_recall.cb_flags)) - return; - - /* - * We're assuming the state code never drops its reference - * without first removing the lease. Since we're in this lease - * callback (and since the lease code is serialized by the - * flc_lock) we know the server hasn't removed the lease yet, and - * we know it's safe to take a reference. - */ - refcount_inc(&dp->dl_stid.sc_count); - queued =3D nfsd4_run_cb(&dp->dl_recall); - WARN_ON_ONCE(!queued); - if (!queued) - refcount_dec(&dp->dl_stid.sc_count); -} - /* Called from break_lease() with flc_lock held. */ static bool nfsd_break_deleg_cb(struct file_lease *fl) @@ -9855,3 +9951,133 @@ void nfsd_update_cmtime_attr(struct file *f, unsign= ed int flags) MINOR(inode->i_sb->s_dev), inode->i_ino, ret); } + +static void +nfsd4_run_cb_notify(struct nfsd4_cb_notify *ncn) +{ + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); + + if (test_and_set_bit(NFSD4_CALLBACK_RUNNING, &ncn->ncn_cb.cb_flags)) + return; + + if (!refcount_inc_not_zero(&dp->dl_stid.sc_count)) + clear_bit(NFSD4_CALLBACK_RUNNING, &ncn->ncn_cb.cb_flags); + else + nfsd4_run_cb(&ncn->ncn_cb); +} + +static struct nfsd_notify_event * +alloc_nfsd_notify_event(u32 mask, const struct qstr *q, struct dentry *den= try, + struct inode *target) +{ + struct nfsd_notify_event *ne; + + ne =3D kmalloc(sizeof(*ne) + q->len + 1, GFP_KERNEL); + if (!ne) + return NULL; + + memcpy(&ne->ne_name, q->name, q->len); + refcount_set(&ne->ne_ref, 1); + ne->ne_mask =3D mask; + ne->ne_name[q->len] =3D '\0'; + ne->ne_namelen =3D q->len; + ne->ne_dentry =3D dget(dentry); + ne->ne_target =3D target; + if (ne->ne_target) + ihold(ne->ne_target); + return ne; +} + +static bool +should_notify_deleg(u32 mask, struct file_lease *fl) +{ + /* Don't notify the client generating the event */ + if (nfsd_breaker_owns_lease(fl)) + return false; + + /* Skip if this event wasn't ignored by the lease */ + if ((mask & FS_DELETE) && !(fl->c.flc_flags & FL_IGN_DIR_DELETE)) + return false; + if ((mask & FS_CREATE) && !(fl->c.flc_flags & FL_IGN_DIR_CREATE)) + return false; + if ((mask & FS_RENAME) && !(fl->c.flc_flags & FL_IGN_DIR_RENAME)) + return false; + + return true; +} + +static void +nfsd_recall_all_dir_delegs(const struct inode *dir) +{ + struct file_lock_context *ctx =3D locks_inode_context(dir); + struct file_lock_core *flc; + + spin_lock(&ctx->flc_lock); + list_for_each_entry(flc, &ctx->flc_lease, flc_list) { + struct file_lease *fl =3D container_of(flc, struct file_lease, c); + + if (fl->fl_lmops =3D=3D &nfsd_lease_mng_ops) + nfsd_break_deleg_cb(fl); + } + spin_unlock(&ctx->flc_lock); +} + +int +nfsd_handle_dir_event(u32 mask, const struct inode *dir, const void *data, + int data_type, const struct qstr *name) +{ + struct dentry *dentry =3D fsnotify_data_dentry(data, data_type); + struct inode *target =3D fsnotify_data_rename_target(data, data_type); + struct file_lock_context *ctx; + struct file_lock_core *flc; + struct nfsd_notify_event *evt; + + /* Normalize cross-dir rename events to create/delete */ + if (mask & FS_MOVED_FROM) { + mask &=3D ~FS_MOVED_FROM; + mask |=3D FS_DELETE; + } + if (mask & FS_MOVED_TO) { + mask &=3D ~FS_MOVED_TO; + mask |=3D FS_CREATE; + } + + /* Don't do anything if this is not an expected event */ + if (!(mask & (FS_CREATE|FS_DELETE|FS_RENAME))) + return 0; + + ctx =3D locks_inode_context(dir); + if (!ctx || list_empty(&ctx->flc_lease)) + return 0; + + evt =3D alloc_nfsd_notify_event(mask, name, dentry, target); + if (!evt) { + nfsd_recall_all_dir_delegs(dir); + return 0; + } + + spin_lock(&ctx->flc_lock); + list_for_each_entry(flc, &ctx->flc_lease, flc_list) { + struct file_lease *fl =3D container_of(flc, struct file_lease, c); + struct nfs4_delegation *dp =3D flc->flc_owner; + struct nfsd4_cb_notify *ncn =3D &dp->dl_cb_notify; + + if (!should_notify_deleg(mask, fl)) + continue; + + spin_lock(&ncn->ncn_lock); + if (ncn->ncn_evt_cnt >=3D NOTIFY4_EVENT_QUEUE_SIZE) { + /* We're generating notifications too fast. Recall. */ + spin_unlock(&ncn->ncn_lock); + nfsd_break_deleg_cb(fl); + continue; + } + ncn->ncn_evt[ncn->ncn_evt_cnt++] =3D nfsd_notify_event_get(evt); + spin_unlock(&ncn->ncn_lock); + + nfsd4_run_cb_notify(ncn); + } + spin_unlock(&ctx->flc_lock); + nfsd_notify_event_put(evt); + return 0; +} diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index e17488a911f7..31df04675713 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4172,6 +4172,127 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct = xdr_stream *xdr, goto out; } =20 +static bool +nfsd4_setup_notify_entry4(struct notify_entry4 *ne, struct xdr_stream *xdr, + struct dentry *dentry, struct nfs4_delegation *dp, + struct nfsd_file *nf, char *name, u32 namelen) +{ + uint32_t *attrmask; + + /* Reserve space for attrmask */ + attrmask =3D xdr_reserve_space(xdr, 3 * sizeof(uint32_t)); + if (!attrmask) + return false; + + ne->ne_file.data =3D name; + ne->ne_file.len =3D namelen; + ne->ne_attrs.attrmask.element =3D attrmask; + + attrmask[0] =3D 0; + attrmask[1] =3D 0; + attrmask[2] =3D 0; + ne->ne_attrs.attr_vals.data =3D NULL; + ne->ne_attrs.attr_vals.len =3D 0; + ne->ne_attrs.attrmask.count =3D 1; + return true; +} + +/** + * nfsd4_encode_notify_event - encode a notify + * @xdr: stream to which to encode the fattr4 + * @nne: nfsd_notify_event to encode + * @dp: delegation where the event occurred + * @nf: nfsd_file on which event occurred + * @notify_mask: pointer to word where notification mask should be set + * + * Encode @nne into @xdr. Returns a pointer to the start of the event, or = NULL if + * the event couldn't be encoded. The appropriate bit in the notify_mask w= ill also + * be set on success. + */ +u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr, struct nfsd_notify_e= vent *nne, + struct nfs4_delegation *dp, struct nfsd_file *nf, + u32 *notify_mask) +{ + u8 *p =3D NULL; + + *notify_mask =3D 0; + + if (nne->ne_mask & FS_DELETE) { + struct notify_remove4 nr =3D { }; + + if (!nfsd4_setup_notify_entry4(&nr.nrm_old_entry, xdr, nne->ne_dentry, d= p, + nf, nne->ne_name, nne->ne_namelen)) + goto out_err; + p =3D (u8 *)xdr->p; + if (!xdrgen_encode_notify_remove4(xdr, &nr)) + goto out_err; + *notify_mask |=3D BIT(NOTIFY4_REMOVE_ENTRY); + } else if (nne->ne_mask & FS_CREATE) { + struct notify_add4 na =3D { }; + struct notify_remove4 old =3D { }; + + if (!nfsd4_setup_notify_entry4(&na.nad_new_entry, xdr, nne->ne_dentry, d= p, + nf, nne->ne_name, nne->ne_namelen)) + goto out_err; + + /* If a file was overwritten, report it in nad_old_entry */ + if (nne->ne_target) { + if (!nfsd4_setup_notify_entry4(&old.nrm_old_entry, xdr, + NULL, dp, nf, + nne->ne_name, nne->ne_namelen)) + goto out_err; + na.nad_old_entry.count =3D 1; + na.nad_old_entry.element =3D &old; + } + + p =3D (u8 *)xdr->p; + if (!xdrgen_encode_notify_add4(xdr, &na)) + goto out_err; + + *notify_mask |=3D BIT(NOTIFY4_ADD_ENTRY); + } else if (nne->ne_mask & FS_RENAME) { + struct notify_rename4 nr =3D { }; + struct notify_remove4 old =3D { }; + struct name_snapshot n; + bool ret; + + /* Don't send any attributes in the old_entry since they're the same in = new */ + if (!nfsd4_setup_notify_entry4(&nr.nrn_old_entry.nrm_old_entry, xdr, + NULL, dp, nf, nne->ne_name, + nne->ne_namelen)) + goto out_err; + + take_dentry_name_snapshot(&n, nne->ne_dentry); + ret =3D nfsd4_setup_notify_entry4(&nr.nrn_new_entry.nad_new_entry, xdr, + nne->ne_dentry, dp, nf, (char *)n.name.name, + n.name.len); + + /* If a file was overwritten, report it in nad_old_entry */ + if (ret && nne->ne_target) { + ret =3D nfsd4_setup_notify_entry4(&old.nrm_old_entry, xdr, + NULL, dp, nf, + (char *)n.name.name, n.name.len); + if (ret) { + nr.nrn_new_entry.nad_old_entry.count =3D 1; + nr.nrn_new_entry.nad_old_entry.element =3D &old; + } + } + + if (ret) { + p =3D (u8 *)xdr->p; + ret =3D xdrgen_encode_notify_rename4(xdr, &nr); + } + release_dentry_name_snapshot(&n); + if (!ret) + goto out_err; + *notify_mask |=3D BIT(NOTIFY4_RENAME_ENTRY); + } + return p; +out_err: + pr_warn("nfsd: unable to marshal notify_rename4 to xdr stream\n"); + return NULL; +} + static void svcxdr_init_encode_from_buffer(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p, int bytes) { diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 505fabf8f1bf..e85cce4f8bc5 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -201,6 +201,7 @@ struct nfsd_notify_event { refcount_t ne_ref; // refcount u32 ne_mask; // FS_* mask from fsnotify callback struct dentry *ne_dentry; // dentry reference to target + struct inode *ne_target; // inode overwritten by rename, or NULL u32 ne_namelen; // length of ne_name char ne_name[]; // name of dentry being changed }; @@ -214,6 +215,7 @@ static inline struct nfsd_notify_event *nfsd_notify_eve= nt_get(struct nfsd_notify static inline void nfsd_notify_event_put(struct nfsd_notify_event *ne) { if (refcount_dec_and_test(&ne->ne_ref)) { + iput(ne->ne_target); dput(ne->ne_dentry); kfree(ne); } @@ -898,6 +900,8 @@ void nfsd_update_cmtime_attr(struct file *f, unsigned i= nt flags); extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netob= j name, struct xdr_netobj princhash, struct nfsd_net *nn); extern bool nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_n= et *nn); +int nfsd_handle_dir_event(u32 mask, const struct inode *dir, const void *d= ata, + int data_type, const struct qstr *name); =20 void put_nfs4_file(struct nfs4_file *fi); extern void nfs4_put_cpntf_state(struct nfsd_net *nn, diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 85574b2a139a..62ac790428be 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -970,6 +970,9 @@ __be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words, struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, u32 *bmval, struct svc_rqst *, int ignore_crossmnt); +u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr, struct nfsd_notify_e= vent *nne, + struct nfs4_delegation *dd, struct nfsd_file *nf, + u32 *notify_mask); extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *, union nfsd4_op_u *u); extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 51BBA3A0E8E; Fri, 22 May 2026 12:29:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452969; cv=none; b=hZR9ZIvMR/Z6TyyZBRomEx9r9d6/tbkUTF0jh6YbDWJMYpbm/z13uXFI7l5L71bYT5KR/2/GI7rIbhCo1pJrVdIit6O9fnyF0j9lfXMby0SmGOsXWMML62P0ars02xrUr4dN30vW73IfulVVbSEUAekYY9GDQnMy9VOZAeKKWz0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452969; c=relaxed/simple; bh=mEnEGZv6+uKTOIKyYYSMR0uBJ9dj3FwKNsNHskjqYZc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KB2cZ0yrD5sA/S4zls9FVvWZRtzXtDMYKCjXuJ+cnF2uRdcXXnR/bBzoeaN9Fpxbh1wRIewxHmDW/ecgV89vKuSJvnruL2AUBkaph6jfuaOUjkp+sSxsVTHu+YT8/APLUyF7sTik59W4tRdRPTxw3zgdXcy7I/GUJ8RjmTB8VaI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dzicd/NG; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dzicd/NG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AA6861F00A3D; Fri, 22 May 2026 12:29:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452968; bh=8l0fFOViIZQZ408K3lRV+hJ1K9YMUbyGPRzWx26nrTc=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=dzicd/NGO15PRO/tBDi48FkmR7Sfy0r2qCXB4yQWxfeaUnsAVnNgsqXGiYjKZTKVj CzPtFdnwlm0M4hJlV/JlmLhlly9x7E4EmF/wPWwitonSN9urofy1SXwNGYoSLYdeMp aGADFGt5jAK8G6BHDNon8gOc4bsFgPvWWqXmWq4FGx7xY7d14JgW31tN+Fh8jjhItN LTc/T5jLJ6weBU/fR31DI6u4P19v8HNQsVz2vmVarvFD/a5U3lp6Fmrw4IFfhacL/Q Y6XhEdyR8bC6q5t10/q5PqX5PnBgun/kz9Zx03wJkAcopUlxLF3mnWptut35t5iG5v iuDZTuW3QwBDw== From: Jeff Layton Date: Fri, 22 May 2026 08:29:00 -0400 Subject: [PATCH v4 11/21] nfsd: add tracepoint to dir_event handler Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-11-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton , "Steven Rostedt (Google)" X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1985; i=jlayton@kernel.org; h=from:subject:message-id; bh=mEnEGZv6+uKTOIKyYYSMR0uBJ9dj3FwKNsNHskjqYZc=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwQQf7iyMobO4tXmgQFWRcrIkwm3g3rf9q/a 3SMHPkE9JaJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMEAAKCRAADmhBGVaC FaYBD/0f5ueCiWM6knSK1JWo1XquINhmtbzGj3nkxnrSEkxMuHeUSPrrkTTfnRhBn/O8xCIxBpT DQYm4MIIEEcHvJle3+xwpXaN0IKEyaTjYirzxz0NpDJr7AbEEhc54ytunDnI2/hcTo4gyD6uRvM v8iSs3mHdPlFxofUUzpbtiG2tSV3KE1oPfl+rHQBZoVIlgmbjJwhthTq2tYvmdV6xLA4YAXFroD B+1JPiUJTljPrmxW7jSI4YK6wsE7FAnJdQlhTSEuC7fU+eQFxssKDM5ykhdfir+xw+JzgBoQ/SY MPWX0jC0PBQl+MirrvOLjW3SGAGfM27yqtcm+giu9s3JOtxMb/lsQjb+HVHk91YpczS92gE1/36 rpwbjYbfY5u5jN24pgN0H3Epdv8B5YTroMzuiijkQHLLR83HyQczvERGOSPZiDhm10J8HSjBCdw n/3/I2CfBAb16/QxEK9W1ssyWshe+X/d9Rf5ipFXmDIExk1AbiPzNgnZzFk28mTILSNW2DLzpj/ p4EqVqwA7LQciH1PlGfKlLNBwoXxTY4lVbkPxWWCuYw/Anv6UCT5GnrRRZJYJ9vOmIB15+TRagh adzA2ppvt5oSzDT9r1MyAmsTa37IBytRv6Rbz0RVwEyemJudsPkCE7p3yid6uk4bn6jytFYeuRp IDLkz21aiYzEsBQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add some extra visibility around the fsnotify handlers. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 2 ++ fs/nfsd/trace.h | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 3afde2e91efe..8d73203297e5 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -10032,6 +10032,8 @@ nfsd_handle_dir_event(u32 mask, const struct inode = *dir, const void *data, struct file_lock_core *flc; struct nfsd_notify_event *evt; =20 + trace_nfsd_handle_dir_event(mask, dir, name); + /* Normalize cross-dir rename events to create/delete */ if (mask & FS_MOVED_FROM) { mask &=3D ~FS_MOVED_FROM; diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index ebf5677c4e73..e8e121a52e82 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include =20 @@ -1377,6 +1378,27 @@ TRACE_EVENT(nfsd_file_fsnotify_handle_event, __entry->nlink, __entry->mode, __entry->mask) ); =20 +TRACE_EVENT(nfsd_handle_dir_event, + TP_PROTO(u32 mask, const struct inode *dir, const struct qstr *name), + TP_ARGS(mask, dir, name), + TP_STRUCT__entry( + __field(u32, mask) + __field(dev_t, s_dev) + __field(ino_t, i_ino) + __string_len(name, name->name, name->len) + ), + TP_fast_assign( + __entry->mask =3D mask; + __entry->s_dev =3D dir->i_sb->s_dev; + __entry->i_ino =3D dir->i_ino; + __assign_str(name); + ), + TP_printk("inode=3D0x%x:0x%x:0x%lx mask=3D%s name=3D%s", + MAJOR(__entry->s_dev), MINOR(__entry->s_dev), + __entry->i_ino, show_fsnotify_mask(__entry->mask), + __get_str(name)) +); + DECLARE_EVENT_CLASS(nfsd_file_gc_class, TP_PROTO( const struct nfsd_file *nf --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 14A7E3A2576; Fri, 22 May 2026 12:29:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452971; cv=none; b=H6UFqlQvRRL5xoYCEGhfQGKppjt5q9Uhnj7GYZEt+FZWQ2Bj+zk/iPNA0KJDb8Laf6B+WnL1bX7WzZfymp4uVCqRvT9O1gIioKyDJDlJIo4OwDyGPoqOyCs+WP67lBZ0YyWl9t20hsQXhho4lvl1trNgLyG5PFsf6lyoPfNPk9c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452971; c=relaxed/simple; bh=WtCsTt7GqWI6wIG7UjJHamJhQxbCqTdMWHwIGmCs/cc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=i+XD08REaQjayV1ZCJhBfWtGCCvUgONGvzXHklPS+j3cyhNnKGjFaAZTUPSdAfWaFNLhmNlSG4RX8JIdxNlfTH8h3BQuBdWEUJl+8KH1S7do8xp44/JmB2uw4q8YOv41HcCcQwi/CWPzdVNdZQIMZf6NpEmYgVxIwmidYq6u2Yg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UAPvCmbi; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UAPvCmbi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7780A1F00A3E; Fri, 22 May 2026 12:29:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452969; bh=pO+8xSv0vMbVLlIOVu1sUSgwIlOn2Ujffy4e7uLZjPY=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=UAPvCmbiOA51t8kBVorYrxYuBY3neAcEdfMEi1B7ByOwVLQWNOZX96+oJ31YT1t4h ZDYFfTwBDIclsG1s/Pi3yp60EObX/rGI8AvGvsNso6rcw1rPjh9COtM6IeolmYTSFU AN4euJVx8OdDLHjgGEVIWx30FqiS3rQQ39ABwWWK6RAF4hVIhsXIry4WFTHHlPVilX EzDozR6fAwFSG5qsCZURqbw5RpN6GZBt0f52pqo75PE0TEx704VWroaf9uk0ZXAQxL uv/VBC7ywjW7dK/x/aMQOUFv/5vcqGy0MaI/gbvnBlNcdeFkSgJasK5AsFgIcLrZQU axKL/dqpFh63w== From: Jeff Layton Date: Fri, 22 May 2026 08:29:01 -0400 Subject: [PATCH v4 12/21] nfsd: apply the notify mask to the delegation when requested Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-12-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1720; i=jlayton@kernel.org; h=from:subject:message-id; bh=WtCsTt7GqWI6wIG7UjJHamJhQxbCqTdMWHwIGmCs/cc=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwQPpkcDHYnYvZbvk0JoHwQtSQagwF34bhka ScyXFE0FtiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMEAAKCRAADmhBGVaC Fb6BD/9qVagnufnnGq9zP3yDYmOfi/0oOUQNY1giyGQDG5kxE9hqQPW1CAJkJnmhLygAypwJo3G kPr1YHdIK1ulgnNvteepynRSQ7oifSy/9p5F0ipDBys49LUTwmoWpfUEikaM4P6LaNqXqRwiX60 ZwQhpQkGDToQQc5uTTU5D+MJet/+wtWA37VM30csDp8Q9HjTFpCel8pmptM7ySP5j4b8aaElwk/ rWncnSjHvoNeuOZm7KzPfk/usutfJU7qKnLE1ONMeApLl/eiY2zNxZMEBsiuuC4wjSFCyH1RPiu 48of22UG7yrCz+e7bFFH2uWIJSBRKvd1wsIIs35UiS1GTkqkB332UmgTTB5520PMvKhWhukOQzj Lw7/sQ9/wniOTD1zXI6WzG/OBh1n9w2PPjVHz7eoVa5ivA9ZbAHrZR41EKb5ELSCnVO9lRAJicn lOTo88oJ17kybF2+MnG8LBfVchdWKK/V3e7ORlg0KApULzZHMnkCF/FnH8nJsm84MDYugtVfNi/ ICMERxMGCa4eiLU901bhrBeZEPhRzTfP4vf9rmdcEICNo7n3mJXO015AAThgJTK7AWfW1ckKg0C FbX67db1SURLCf2IiEadRCrTlNiWwugiQTz1L0GYNPKkf40g8QCEocv/Eyn+x35cOrQNBkxRpSW f4+TnILtxxCMt/A== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 If the client requests a directory delegation with notifications enabled, set the appropriate return mask in gddr_notification[0]. This will ensure the lease acquisition sets the appropriate ignore mask. If the client doesn't set NOTIFY4_GFLAG_EXTEND, then don't offer any notifications, as nfsd won't provide directory offset information, and "classic" notifications require them. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 8561540ab2db..30f338f90acd 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2521,12 +2521,18 @@ nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_c= ompound_state *cstate, return status =3D=3D nfserr_same ? nfs_ok : status; } =20 +#define SUPPORTED_NOTIFY_MASK (BIT(NOTIFY4_REMOVE_ENTRY) | \ + BIT(NOTIFY4_ADD_ENTRY) | \ + BIT(NOTIFY4_RENAME_ENTRY) | \ + BIT(NOTIFY4_GFLAG_EXTEND)) + static __be32 nfsd4_get_dir_delegation(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { struct nfsd4_get_dir_delegation *gdd =3D &u->get_dir_delegation; + u32 requested =3D gdd->gdda_notification_types[0]; struct nfs4_delegation *dd; struct nfsd_file *nf; __be32 status; @@ -2535,6 +2541,12 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, if (status !=3D nfs_ok) return status; =20 + /* No notifications if you don't set NOTIFY4_GFLAG_EXTEND! */ + if (!(requested & BIT(NOTIFY4_GFLAG_EXTEND))) + requested =3D 0; + + gdd->gddr_notification[0] =3D requested & SUPPORTED_NOTIFY_MASK; + /* * RFC 8881, section 18.39.3 says: * --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 BC2A83A48D7; Fri, 22 May 2026 12:29:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452973; cv=none; b=m4D5sk5OIwgsE4q8dtmYf4A3HjkpbgJx7o5r1AefDrxRGgxp9lOshmX0jvz2RtC8+o1LE60o+OwMjZL2paQ1mT1KIJuUQCLlUYwPKYtSR33bmoMwFg+I2A6/fE2L6xClShnASImLD8n4RRM9CiPzxD4A+e9PoH+CzfQlhha2+cA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452973; c=relaxed/simple; bh=AnXDCmJFZYm5CvJ/Tqx4ECFvxiyWh0qg/VdF8Hlk1hE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rg71vnDRgiII2JSZ23wIz+p+4SIZa46YDXYcB6Zc/8I1jfs0xtIyWDgvmNFZM95OMQQZe8FhnNo33xCIyibOTB9cCbJkyfg+10YCFi3436cwxodwTEczU9mcI71VhviGzosWKpOx6BJxxXQyTK/C5cSfOUFS/mxeaFBunHvVV0w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TjgiMdF2; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TjgiMdF2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2DEEA1F000E9; Fri, 22 May 2026 12:29:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452971; bh=DF5gZGDIA/XCxzRoqwszAdw1M2a+k5vgSFZ3a7XrlYQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=TjgiMdF274AtYLga4CFcFoiYm1itTPjMItwSrX+kNfTSvmz4T+5CZoRCLtUbTP03z V7DhRwfgVRuAYJ/58+Rglz3qDxOT8rLKeLPyoRVvHNzMukOxQJE+iYS79Vr1EDfrMl MXG5FcgVW5ap3DmPNFoFXULMDNnew14ODJcroIFyH3pOiAYJeFzDi6DlGT+HRgQ1nt uJWSDJVYT0VK6o7TTNMBqEVz3/3JqW9LFR0zPIdCNsRQGYPeD3h6KYf6Qcxm3Y/GuH 8omUGGuF5QH6OzXAH5y0UlGpn9vlKDui5j84hXvkAfACKh4drJUmin5uSJmVyOkXUO kgBmh9KvE5aSg== From: Jeff Layton Date: Fri, 22 May 2026 08:29:02 -0400 Subject: [PATCH v4 13/21] nfsd: add helper to marshal a fattr4 from completed args Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-13-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3412; i=jlayton@kernel.org; h=from:subject:message-id; bh=AnXDCmJFZYm5CvJ/Tqx4ECFvxiyWh0qg/VdF8Hlk1hE=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwQ1Xy4/+h15uJyIJgCjn5Myku7W3gEQQ3K9 uwHfuK0Ls+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMEAAKCRAADmhBGVaC FQuQEACwkhh+QxwgKAXrDjpeCkNBgW5Chaq1anscNlAOeRQkfX40WS9lCkE+4o6ucCoMTt+WDZm iu1e3Cx8eNtSJDxHC9sOoBJmMPOSvIDR08BVDewPFiFk8hHv2GqNcH490d7lO0F7BcICw2xxtKg uY4/mm/z/itbrSbPB0UOONvab1t4xbSwGDgZiROcMROFZdPALLS3apMTXjMu2dTBZJATH5lR+y1 3KwmmGl+K3NlowD8/0lPtp1H4+65B6xXF2EtqzLqY9NWey2lUDw1hPDKvMF6I9uuZx0wjL+Ud1x u18IJ8/noJfkG9sPOJ2U5P+XGUAGVy744MWpgn3Bu1K00sIuK6dPUcnHofT1Nrd+OM3kIuF4kK8 qatIKNtx76QxshniNtNhqSYOQf0NYAuTotcC0/f+2t2aAjHP9afmTHazxjyxvtflvJtX/TW1HX1 D0SQgVUSJYNWqeScvsT6qgj+wJHYIazg4DsH5+SBffa83csiXX1GXNIlN5dLrlySt/mUYTo1qOC wXTTeophVnoHt8ZXRK83Mj0SQkj6VjgNHvlOdrg6jekwLtn1a8Zn1Mk0wAxL6UnU9kjP1gSEayu /kb2mspoSvUlutM97wGEDienWMNEfWz1xWcYvvnJKLuLiXGgCWXz/M2l95kenMUg8TsTsjdiX0T T/0v+ZOq/bDy7dA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Break the loop that encodes the actual attr_vals field into a separate function. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 31df04675713..703caa2ee7dc 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3882,6 +3882,22 @@ static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_= ops[] =3D { #endif }; =20 +static __be32 +nfsd4_encode_attr_vals(struct xdr_stream *xdr, u32 *attrmask, struct nfsd4= _fattr_args *args) +{ + DECLARE_BITMAP(attr_bitmap, ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops)); + unsigned long bit; + __be32 status; + + bitmap_from_arr32(attr_bitmap, attrmask, ARRAY_SIZE(nfsd4_enc_fattr4_enco= de_ops)); + for_each_set_bit(bit, attr_bitmap, ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops= )) { + status =3D nfsd4_enc_fattr4_encode_ops[bit](xdr, args); + if (status !=3D nfs_ok) + return status; + } + return nfs_ok; +} + /* * Note: @fhp can be NULL; in this case, we might have to compose the file= handle * ourselves. @case_cache is NULL for callers that encode a single dentry @@ -3895,7 +3911,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xd= r_stream *xdr, int ignore_crossmnt, struct nfsd_case_attrs_cache *case_cache) { - DECLARE_BITMAP(attr_bitmap, ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops)); struct nfs4_delegation *dp =3D NULL; struct nfsd4_fattr_args args; struct svc_fh *tempfh =3D NULL; @@ -3910,7 +3925,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xd= r_stream *xdr, .mnt =3D exp->ex_path.mnt, .dentry =3D dentry, }; - unsigned long bit; =20 WARN_ON_ONCE(bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1); WARN_ON_ONCE(!nfsd_attrs_supported(minorversion, bmval)); @@ -4124,27 +4138,22 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct = xdr_stream *xdr, #endif /* CONFIG_NFSD_V4_POSIX_ACLS */ =20 /* attrmask */ - status =3D nfsd4_encode_bitmap4(xdr, attrmask[0], attrmask[1], - attrmask[2]); + status =3D nfsd4_encode_bitmap4(xdr, attrmask[0], attrmask[1], attrmask[2= ]); if (status) goto out; =20 /* attr_vals */ attrlen_offset =3D xdr->buf->len; - if (unlikely(!xdr_reserve_space(xdr, XDR_UNIT))) - goto out_resource; - bitmap_from_arr32(attr_bitmap, attrmask, - ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops)); - for_each_set_bit(bit, attr_bitmap, - ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops)) { - status =3D nfsd4_enc_fattr4_encode_ops[bit](xdr, &args); - if (status !=3D nfs_ok) - goto out; + if (unlikely(!xdr_reserve_space(xdr, XDR_UNIT))) { + status =3D nfserr_resource; + goto out; } - attrlen =3D cpu_to_be32(xdr->buf->len - attrlen_offset - XDR_UNIT); - write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, XDR_UNIT); - status =3D nfs_ok; =20 + status =3D nfsd4_encode_attr_vals(xdr, attrmask, &args); + if (status =3D=3D nfs_ok) { + attrlen =3D cpu_to_be32(xdr->buf->len - attrlen_offset - XDR_UNIT); + write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, XDR_UNIT); + } out: #ifdef CONFIG_NFSD_V4_POSIX_ACLS if (args.dpacl) @@ -4167,9 +4176,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xd= r_stream *xdr, out_nfserr: status =3D nfserrno(err); goto out; -out_resource: - status =3D nfserr_resource; - goto out; } =20 static bool --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 BAEC538D41E; Fri, 22 May 2026 12:29:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452976; cv=none; b=n1nWaL1Nq++em3ELozWGPoGQ6FVyTFPeJZzdU7oWnepTowOZYv7fzKsmi2iWnF5RrhE+wpWahI9b9ZwHPQk1Z8RsRN1GGnjthpjLt9rxMJjn19YMonGhCjQY+6WbFEM1KQyjAWKLyKi/eSuv4hV3jy7LYgjtcfI9lmuuqlrD4Ic= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452976; c=relaxed/simple; bh=/nJ1xNNDJ9rJbf9EQXkdUUjwKKr61STzhNKZjVXGJbQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Jtzd0lTd1GCoCRzXGEoeFMhwrGx13RUFleOykpjZJYR+jFI9iIx1zkW9DuELTW+qdrw+zNAqiueHRrI7sP/FJKFHuGhW/dgwFGZOfJpgNXGJihQmU8kkMb50VKx5/HF5tfO1kNMhh1e5r/D6+UY9FidePr4TbAIB8MzJuDJz1Ng= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=E3MOTyB2; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="E3MOTyB2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D83121F00A3D; Fri, 22 May 2026 12:29:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452973; bh=0psYgh/U78Yx/gV/O/+YpCNlLQ0kiZOK/pcEbcuUCHM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=E3MOTyB2uzyPZfZg9w3hupua6pYUhICZ7zgOz5jF1hq1h4/8Y1TKQy473Ii3d1viG zSwHoeizkAhBZrU5wdYlcGneYk338L4F1yWhpdubW4Z1rdP0B+CGLlVbt9/bOTPXXS wPU1Ul/QhN2jAVqfGmsBIsXAnBjVSncIfw76jamHZTKk/vevP9xuM+Y4ixESItOgsT 1cMAaYh2KmNsLpEfzlm6dp2HcxAj9gEQjoZFiJU9BhME+8Y1/6sAjDnaST5n4fZKJg 4PH1kwb3g/f3P8PEQYM1Tjf56vtPyMz3XtsFFLJLeIfta3bPEZPyRJFgK9nNqPOlmk LlDP3XlmyicOA== From: Jeff Layton Date: Fri, 22 May 2026 08:29:03 -0400 Subject: [PATCH v4 14/21] nfsd: allow nfsd4_encode_fattr4_change() to work with no export Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-14-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=846; i=jlayton@kernel.org; h=from:subject:message-id; bh=/nJ1xNNDJ9rJbf9EQXkdUUjwKKr61STzhNKZjVXGJbQ=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwRj6eihuUUzU2n1LZSLtq5yqJVFVEmCi5ML m0/pfbwIWCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMEQAKCRAADmhBGVaC FQkqD/0b/+W7P/ZPj6Y3VwDFVLoiSj395pW+ThnHLTlRNXvsDsdN/g0sn8uCTuNzZmFQy8F8qVl CJhRlj1HQHFqNi5KOBqKQYxXNY2RVbbSNre2z7LA6hzodwNGAT/LzWWyEc6OTmw51vsWDV57cLE 2gD9QFuLJZhYdAi6oGaC5IABbeo9LvE6ouu6+trqdn++A6F3l2mGGYxLHA3TbECxg06AU4Tdozl BVpo1AH0XDxsWnKpeb4JbcIbvZH2RRrEL9hKRFoOfcrPEBxFboSmqXjzop9mbsy8n1ei51MINAP V+bOPIWkYZvpPIoQQPckuNH4XgaghnV0iRAAL12kPwhQQ14rCsY73D7Y2ZXj3w6lcsskQ68vM+4 VrUbgUQdqAbhC26IktQArwVhodDu6bU7R2FyYbUYvjNah5360TqrZfTn4LetWQfYYvbnxIe/SW3 ir6HvGMnkrksOFCvgv1HAbisvJKcmrwuLn+msiDk7iznJ1af6YkwiNyETvIYiitHNwfiGkK1eSv aM4p+MYnfu7NI8AlEOXGJeDKcsXVbWYMa+3WZLrY7iCLh/vKnAZzuIUc04OKZAVMItTc25VRaQy Z4yHU5B8ubb2SLZuFI+zzCB58YibUCOBWHr4UWpyB7WRmMwOT3kki1pSpNuHfLYmUN+vujv98Th z3COQl1Hm0l2cLw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In the context of a CB_NOTIFY callback, we may not have easy access to a svc_export. nfsd will not currently grant a delegation on a the V4 root however, so this should be safe. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 703caa2ee7dc..1fc4ce2357c0 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3260,7 +3260,7 @@ static __be32 nfsd4_encode_fattr4_change(struct xdr_s= tream *xdr, { const struct svc_export *exp =3D args->exp; =20 - if (unlikely(exp->ex_flags & NFSEXP_V4ROOT)) { + if (exp && unlikely(exp->ex_flags & NFSEXP_V4ROOT)) { u32 flush_time =3D convert_to_wallclock(exp->cd->flush_time); =20 if (xdr_stream_encode_u32(xdr, flush_time) !=3D XDR_UNIT) --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 1F1FD3A6B94; Fri, 22 May 2026 12:29:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452976; cv=none; b=MNzM6S50DudP2ZH7KDayDe7OyMVFFAhP6WwcqaocGEuTmotolE7iVWwe0EfNgM0aYCnxW8zZMK0tju/bnEkmR1BdLKx4OZdU/0bpRVRggE9+egSSTNmPk4w1P2kHXlMf52yOC+Zq9cG9znHNzoccHBAWiya7cR16u5zkpJz8qzw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452976; c=relaxed/simple; bh=JWk/qJly9oa5aSU4/ANb1Pj0gnrjFN99OCHUHA/X9VU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AU/zAg+2Wa7Y9LwL8Kp8kSnFHJA0S6O6JMmsNV0/4Y8EQx24o3t8vuSyYQwH5aaupFQ1Lt2qVDMnaq+AxXdO6lwav8WHYRpTgsj3kYczxxlnJRlAl8OSdT98Puc7gmZlrAvUDgcYYjlQlID9kt7Rk2OGY7qfW7+N2Dslfu6VrDk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eblgCfZZ; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eblgCfZZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8E52D1F00A3E; Fri, 22 May 2026 12:29:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452975; bh=MK6ljeFsXZ3jOZigE4+tZvoHGJwTrFzkGpt7U+sHsGM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=eblgCfZZ/ebBoWp6USPj+LYCKW363/DXns/TNW61OvUep096rkzWCpoqoBPCdBvyp 2DdE1pP0dVK3vtcY8x3VfQdwGSyviqEgG3nPIzjTA/PxZyxwIrynkXsb9Uc010tat2 syMqy1kKvgYzZ7SSRKovxDHdJ5DP8mCrdZ0Bi3VV0kr1PoWPJqR9xSJinl7DPOqIS1 dCbpnhsKbK8lIwTCcBm3128lqSwpfakw4ABqjA7DjLQ2Nw/jZ8izf13f49RiB4XpIm Q2bicBBfyQt74CHRUeN6Y5hDTjoA9FyhmoRrMb31xTXuCV3kmOToudp9WmbicD0vbm BO569AXYZli9A== From: Jeff Layton Date: Fri, 22 May 2026 08:29:04 -0400 Subject: [PATCH v4 15/21] nfsd: send basic file attributes in CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-15-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2682; i=jlayton@kernel.org; h=from:subject:message-id; bh=JWk/qJly9oa5aSU4/ANb1Pj0gnrjFN99OCHUHA/X9VU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwRiJW3cB99VH2cQKa0gszLGXbJxQSliMcgH JwIZQbAFqaJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMEQAKCRAADmhBGVaC FcEREAC9sL7KvM/yk8Z0d6fas28a2AtGDJycpV/Kxv2oTtW3NtGZZo5FhXABbt4FqTA2zy1PxRZ 7mw1XOWjXZ5OpriXuMX7t3LPpRy24iLoisgSXD4MkP1aNk4Ie3cDS4OAs8Dr58Avdn8oC3cwuFn ne56EIxCOA/Gnkzf0YSrTPjvZqvg/+gfdn9gbb3Q7QTXxEuwANqXG8Zcc0tjCiIfJN1JrpVc127 UgtIeCZVNXm10QtvZLpox9uQAvNpeWK5vcIV4IBvMc9XpTBWXPrsxw0bEGNVpMhNoOt7RT+rL5O 8of37tKB1CSCrcw0EQPXeop4UywYT8Wy19LHDdVeCEfsqlWALv5DjiEIMVA2ySMVSi5GGqad4gG R7XMiWnGiPtbsaOzJhLbAN7cv+gr6nE56qBEaKWMhxdaSbuQNPWXiAasvvA7ks83AdHR606kpBs YmKFpBWhZseR3WMGhzFfz8i4ppvzvwot8FKNVuV6EImkzBE7TESMU3NgqCjDGuH1HBNvx0ovMfj NY91gURQzf4QkYik72i2jFz7xURUPoP0Z0FjDTnGlGEwfltpOe3vswZGkLHIo7WpNaYS0QT6xCY uqzcb1jnshCpstaoxwV/jCP1iAZd2jQ5bg8pU7tibMI+plqeMHVRBGXzeRKgHSlw3ozHAD+afEm vQZXCj4Dba4Z8xQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In addition to the filename, send attributes about the inode in a CB_NOTIFY event. This patch just adds a the basic inode information that can be acquired via GETATTR. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 1fc4ce2357c0..61c555446f63 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4178,12 +4178,21 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct = xdr_stream *xdr, goto out; } =20 +#define CB_NOTIFY_STATX_REQUEST_MASK (STATX_BASIC_STATS | \ + STATX_BTIME | \ + STATX_CHANGE_COOKIE) + static bool nfsd4_setup_notify_entry4(struct notify_entry4 *ne, struct xdr_stream *xdr, struct dentry *dentry, struct nfs4_delegation *dp, struct nfsd_file *nf, char *name, u32 namelen) { + struct path path =3D { .mnt =3D nf->nf_file->f_path.mnt, + .dentry =3D dentry }; + struct nfsd4_fattr_args args =3D { }; uint32_t *attrmask; + __be32 status; + int ret; =20 /* Reserve space for attrmask */ attrmask =3D xdr_reserve_space(xdr, 3 * sizeof(uint32_t)); @@ -4194,6 +4203,41 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne, = struct xdr_stream *xdr, ne->ne_file.len =3D namelen; ne->ne_attrs.attrmask.element =3D attrmask; =20 + /* FIXME: d_find_alias for inode ? */ + if (!path.dentry || !d_inode(path.dentry)) + goto noattrs; + + /* + * It is possible that the client was granted a delegation when a file + * was created. Note that we don't issue a CB_GETATTR here since stale + * attributes are presumably ok. + */ + ret =3D vfs_getattr(&path, &args.stat, CB_NOTIFY_STATX_REQUEST_MASK, AT_S= TATX_SYNC_AS_STAT); + if (ret) + goto noattrs; + + args.change_attr =3D nfsd4_change_attribute(&args.stat); + + attrmask[0] =3D FATTR4_WORD0_TYPE | FATTR4_WORD0_CHANGE | + FATTR4_WORD0_SIZE | FATTR4_WORD0_FILEID; + attrmask[1] =3D FATTR4_WORD1_MODE | FATTR4_WORD1_NUMLINKS | FATTR4_WORD1_= RAWDEV | + FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | + FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY; + attrmask[2] =3D 0; + + if (args.stat.result_mask & STATX_BTIME) + attrmask[1] |=3D FATTR4_WORD1_TIME_CREATE; + + ne->ne_attrs.attrmask.count =3D 2; + ne->ne_attrs.attr_vals.data =3D (u8 *)xdr->p; + + status =3D nfsd4_encode_attr_vals(xdr, attrmask, &args); + if (status !=3D nfs_ok) + goto noattrs; + + ne->ne_attrs.attr_vals.len =3D (u8 *)xdr->p - ne->ne_attrs.attr_vals.data; + return true; +noattrs: attrmask[0] =3D 0; attrmask[1] =3D 0; attrmask[2] =3D 0; --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 17CE13A7831; Fri, 22 May 2026 12:29:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452978; cv=none; b=gLNn9ZfiDZ9L7/deygEcht91B/Tyavg+NDnclioZyZHYtrvCTPX8M3ju2YjAHP2Xd2yb+1vfpaG/Lk+fPUwgPRcWc5iYrgQwSZZMLbPHqxnH5u86XaVV2zFuVrbgXQ5t8sXDlIIkQrqkAeY6h6Og8i3tNipzqQ6HCTYZcqoaeNQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452978; c=relaxed/simple; bh=ObaqPlpMBYi+3KqTXL6Uij26L0eMDEbY8kbhU/u7/vw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SY2qnXp7g2i+0YJY4fM1YvKcuDNR9EmSL7I2i5zVM9hwSRihftAYIqBZO0w7+gmcoQe+Px2Zst6jXac2o+yXGT5tqNX2u2XBKCF4fLEI8LnDsQZ8twPqpXjoEIyiVPZWnpkkpSiItvRhPRHPdXULMr6QwctqLjUGlLKSTT+y0Ok= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lXmon9H0; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lXmon9H0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 44B251F000E9; Fri, 22 May 2026 12:29:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452976; bh=P7GJcWlAnn9onaeiQvrINQHRw0BOo7qTCfQLKMtXhO0=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=lXmon9H0AqaUZRtJITdLeI+d3nSaFU7Dm8LVjpLqvUQ6XAhxVDmr/cj+pBHdyKy5l 7ltCrXev50Ut6rZwuV1Nlz8HtffzCDrwxVq8WDHwMVA19VkmfW69e4wXoo+TXBQxOR y1Kuyjxno77x3SO5ZVovk/iTZAKu86LSm0FWgHEfV7WyCSlLKoNnOFrTg9xuSHrsEW 5y72QAW5o9JCka4Ohxf88I18CZj8PqSCgST3XGeW1ilVNcja92CrcRlAn2tApJcPmx iE2SNnrWywYw5/RvxfcgxOKlJwEGJPqxmBmwDaegfa5XICAFZE/ahJf+XftkWXBMWI taFgdX19kThiA== From: Jeff Layton Date: Fri, 22 May 2026 08:29:05 -0400 Subject: [PATCH v4 16/21] nfsd: allow encoding a filehandle into fattr4 without a svc_fh Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-16-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2608; i=jlayton@kernel.org; h=from:subject:message-id; bh=ObaqPlpMBYi+3KqTXL6Uij26L0eMDEbY8kbhU/u7/vw=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwRIq7lhQgCSyGV+5XU8EeN1NLbBa/bT8y3v ebDsRidpXSJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMEQAKCRAADmhBGVaC FXjvD/4h15vcGkFB2WPLqgPIsGFcKImv++YuRY8Kl6la5b2QkUGkIbu44Y6gqhbGMmVc432DyPk SRBnDENzBcRpivvRVrFBA+Ky4qHXr93Tf6awxi6xW/q7BBSYPADth36JgksrGtS4ED3TWmNjBsx 6RNoKchoJaiNfV1gNXYwQpj4SunDueQs1DyU/gsZakeWnevWcYSA/Nt0GEin1QgIPJIW1jIqsCg uKs4PA97FPusw80d13JZUd6grdqjPwcfGgH2tjM4f/2/Cer8oLprcV2QS1P2M3JbAhrLEoX62k0 W1CV4O6PB+kw2bxb+nXZVwF7XAlF0RqsjCqMWCQsOg7tr/Ow2urHeZrqdlE0Il67NNkYb0SiRgh eDWns0eQ6uCWLjNl/kIVMpQnDz49U0yyNWSTxiAzes8+1PzonJXjD+b6JioebfefoojLaOG9D6T EETHviT7na968+uLePPM79NCuaV3WrQu47D9CQ9++k+cKmp7as2jX2b66acevnW5fW3k6bU4qYn o+Mv8WhT9tHSySwAEAbrO5EE5yMMGI/CzWBmnn21zEgNhvwFkbRSc/SnrNLIMwjdLr6rkchktC2 eNRK58NUWTM7xOLNKffk02VPvIX/2zch1lrJGcEDAJPd1ZZ87XH5Tc7O2zOVytM4WghFsB8Pgat ULr3K6zrEYNkksQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 The current fattr4 encoder requires a svc_fh in order to encode the filehandle. This is not available in a CB_NOTIFY callback. Add a a new "fhandle" field to struct nfsd4_fattr_args and copy the filehandle into there from the svc_fh. CB_NOTIFY will populate it via other means. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 61c555446f63..33b6cd492e56 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2702,7 +2702,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) } =20 static __be32 nfsd4_encode_nfs_fh4(struct xdr_stream *xdr, - struct knfsd_fh *fh_handle) + const struct knfsd_fh *fh_handle) { return nfsd4_encode_opaque(xdr, fh_handle->fh_raw, fh_handle->fh_size); } @@ -3145,6 +3145,7 @@ struct nfsd4_fattr_args { struct svc_fh *fhp; struct svc_export *exp; struct dentry *dentry; + struct knfsd_fh fhandle; struct kstat stat; struct kstatfs statfs; struct nfs4_acl *acl; @@ -3389,7 +3390,7 @@ static __be32 nfsd4_encode_fattr4_homogeneous(struct = xdr_stream *xdr, static __be32 nfsd4_encode_fattr4_filehandle(struct xdr_stream *xdr, const struct nfsd4_fattr_args *args) { - return nfsd4_encode_nfs_fh4(xdr, &args->fhp->fh_handle); + return nfsd4_encode_nfs_fh4(xdr, &args->fhandle); } =20 static __be32 nfsd4_encode_fattr4_fileid(struct xdr_stream *xdr, @@ -4002,19 +4003,24 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct = xdr_stream *xdr, if (err) goto out_nfserr; } - if ((attrmask[0] & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && - !fhp) { - tempfh =3D kmalloc_obj(struct svc_fh); - status =3D nfserr_jukebox; - if (!tempfh) - goto out; - fh_init(tempfh, NFS4_FHSIZE); - status =3D fh_compose(tempfh, exp, dentry, NULL); - if (status) - goto out; - args.fhp =3D tempfh; - } else - args.fhp =3D fhp; + + args.fhp =3D fhp; + if ((attrmask[0] & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID))) { + if (!args.fhp) { + tempfh =3D kmalloc_obj(struct svc_fh); + status =3D nfserr_jukebox; + if (!tempfh) + goto out; + fh_init(tempfh, NFS4_FHSIZE); + status =3D fh_compose(tempfh, exp, dentry, NULL); + if (status) + goto out; + args.fhp =3D tempfh; + } + if (args.fhp) + fh_copy_shallow(&args.fhandle, &args.fhp->fh_handle); + } + if (attrmask[0] & (FATTR4_WORD0_CASE_INSENSITIVE | FATTR4_WORD0_CASE_PRESERVING)) { /* --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 803C1390C9F; Fri, 22 May 2026 12:29:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452979; cv=none; b=nSNXklahxec2xZZo5zokciAsn3bZNkYXkCo9q+un10G8wR2bZs4aEAdtqJRK5v5dzK1/9aQNycDTp6Gj/mnYj4rgP+D4T0RW3xlIhjtYYaAeYaW1oBAd9ikUk3wVuyarPySsnec3LJbs/jQfinaIue981JZZ1JdxyNscoiVt7w4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452979; c=relaxed/simple; bh=S54+rM2MVj7+wJMZyyeIWuif9qM1/ds9J+LGy3XQ7rA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ahr5/jS00pKP5zttmydyDG1luC8bhe++cA4wmdU06/ZtEpswis6znxPbnoSlEeeJ1K617+f+UrukoUCTni6QnMkB+D7WugJCXzD6F96XZYZluf7c14BYRO3uZa8DoUENtzzy19F+Klih0jM91JyEZfNpU/1/ZtHP5pQm12mM5+s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=O+KYX0Q1; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="O+KYX0Q1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EEC7E1F00A3D; Fri, 22 May 2026 12:29:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452978; bh=jr45dfm3eg1LVF54YsyaZn/ElrojpeyWCBSxVhPwhqA=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=O+KYX0Q1qvMSjzPT9QSV4eMMc17djLQ5xgCKI7LJIn9c9jhByIw4gSTfzcekSlSTe ZZcl51mb8EfLL+essRve13ypFCFNEzFfUzR8S1NX41OJcK0pkTZL2dEVntkSGTJbR1 +767kJefV25kQNFDlCR0/3+5lY4niyAjS0H3NS49uzRrkly8XAtuE2oX2lprOn/47o s76PnMeg4enjt2MNAnuGaDGLO4Ds/o33dGaVy9d4/ZbmYOFjolWxoEbqt6F87i8BEo pLReZdFK0N59vLjUK556nbUwhmdi3EOC33RxFKU0kJ7DEAWc9pqvfn4svYEzIwZ6b0 JSfpkZPirD4Sg== From: Jeff Layton Date: Fri, 22 May 2026 08:29:06 -0400 Subject: [PATCH v4 17/21] nfsd: add a fi_connectable flag to struct nfs4_file Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-17-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1426; i=jlayton@kernel.org; h=from:subject:message-id; bh=S54+rM2MVj7+wJMZyyeIWuif9qM1/ds9J+LGy3XQ7rA=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwS132hE/a2nn3fji0wPuiTkk/b4LusByI7M U99c5M+WWWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMEgAKCRAADmhBGVaC FSHND/wK65W43OA8yudK/QDGEGTrvGiz4AxKLBhRR+1WxzIsLB1iacvvz0zTupEB+1U4s+dIvmp g1aavgj+8X0PCPvbgOUjbnr39b582AyHQAH4MshKMxnp8xdIoEQLxbw34kXSGxl67lmYvyFPuit KPBTUDY5ccm3IyUaoCYGhphsEa11/ZeJYUWeelTGGZfAWA7Ept5NdcZDTZmVVtr7f3xPIWjcnY9 jYZ9MARh2W7QvxS/Z7nc3D0h6hT/EuwwljkEY+cq+QMJhaMzEe7QhHxc+LjclIHy0Ge4NhgqWom CLRtxUC2r0ex0aSVwanhACEx4K0mxjtzxtPzs7zt6iBO309Fj6r/qfnX0s5aARYCEjwI6JAAlwJ RlUI/FnKZEqa1SzZbsMtbM6MoPJRU66fQ7cevon7PrIEUHJlqUMOp9+zvP269zKSeawLjijBWSI FyOquqF0UcKq7s+hPsTvhQrr2xakZrdXe/XXOzMUAO3qSFBfKP308cdS3oONd/gZ6+X/DVqM6p4 v8RnGWKXaMiTjH3MZuCs8vkBsXDj8si5fP6kicvgEIImF/qIfFbbwTqX0XJeEFelpdDxbXfot6E i/CG4aiMuAQwtq65sgo0cuaXiqQvmGP4g12YxLUpl2An7wfyXvNPQzWqCuUxrvtRXfP4FEGNcbB 2EMtAQXywZ7Uw2w== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 When encoding a filehandle for a CB_NOTIFY, there is no svc_export available, but the server needs to know whether to encode a connectable filehandle. Add a flag to the nfs4_file that tells whether the svc_export under which a directory delegation was acquired has subtree checking enabled, in which case it needs connectable filehandles. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 1 + fs/nfsd/state.h | 1 + 2 files changed, 2 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 8d73203297e5..0e7512046c63 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5175,6 +5175,7 @@ static void nfsd4_file_init(const struct svc_fh *fh, = struct nfs4_file *fp) memset(fp->fi_access, 0, sizeof(fp->fi_access)); fp->fi_aliased =3D false; fp->fi_inode =3D d_inode(fh->fh_dentry); + fp->fi_connectable =3D !(fh->fh_export->ex_flags & NFSEXP_NOSUBTREECHECK); #ifdef CONFIG_NFSD_PNFS INIT_LIST_HEAD(&fp->fi_lo_states); atomic_set(&fp->fi_lo_recalls, 0); diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index e85cce4f8bc5..56008234b700 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -747,6 +747,7 @@ struct nfs4_file { int fi_delegees; struct knfsd_fh fi_fhandle; bool fi_had_conflict; + bool fi_connectable; #ifdef CONFIG_NFSD_PNFS struct list_head fi_lo_states; atomic_t fi_lo_recalls; --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 3872A3A83A8; Fri, 22 May 2026 12:29:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452981; cv=none; b=ZVIQGNOR2wGftpvIRDpxOG8eeW+yPHIu9SEErlQdhpUHzDt+P/MHEuGy200HbYr7BbgcQqtTMNlnvisBvcBBXrYa/hWL46d/GflxzQfkJoyZBJaHYz3g1QsxOpNr3rIrAGz/Wsza8QUQw5qPK378n2JHXYw7YvdDxofSaSzwN0A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452981; c=relaxed/simple; bh=Y50oSV6B/JehwRBE6ozp3wxwE6QnIRaFrxKuDBSJhao=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WZk2PoE8BkqTLJp+m5UkCyumq77dJQDT/+sdm31s6VeRd3lRX1h0WBKz3rD9ZKuLNcsqMT2yoqlv8Y56PzhC3oVfiW5Hyq+XOIX4Ty7N8STl7cWKhOAkDk5ZZBHEe5YacGUSMi0CPXnQhH/pX1vx3GlO4C2ju49rMM/W807psdQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=A5ixIoJQ; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="A5ixIoJQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A5BDB1F00A3E; Fri, 22 May 2026 12:29:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452980; bh=SNn+vri9RRR9gMRxnX7erNj8H9djqSG4aGq8GD9k76c=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=A5ixIoJQN3QU4DFZD1i73Hbe+o/1jaIvTkqvcNe+TDRe4Cne4pZvB2mhcYpbv77ps yv5fya7qwB+P6gFGxPYtGO12+0S3fFO4Q3WoDBkTapwfYrXj3TWFodnB5g298Q6bJK q7zWm5qW/lINaOLaCUr5kKAEOmkyioeZAQOzYP3bzFt54eDILiQA2Iyk+GwUjgPogS GRry78RhC4x179ReqDPOzwXPRVoPJNy3taUqEyjRT7kxULHjfnWlWKgfyfYime22BB LG3cFY2WWNvfFA3Y+LI+8ns803N6etv0sCPWieXDPjXhKkAwobAHM2buQxTxwJD316 LK4U2dtbAC5Zw== From: Jeff Layton Date: Fri, 22 May 2026 08:29:07 -0400 Subject: [PATCH v4 18/21] nfsd: add the filehandle to returned attributes in CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-18-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2618; i=jlayton@kernel.org; h=from:subject:message-id; bh=Y50oSV6B/JehwRBE6ozp3wxwE6QnIRaFrxKuDBSJhao=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwSNRCRzGHOr9nAg+FtjPukeM5GHrjVMLn0R VImJM9a1ZqJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMEgAKCRAADmhBGVaC FY++D/43gLaw9+PHGjAZuS5NJOHtmkYGIgeYVoKpWALgVNpcrT0Pg31VrILLAeubWO3NmwmiraK +F580ki7Z1y4Q/NUmTK5Sr0aWvLRBdLbTpoCgGwiC9RqgGqibGDl1CF9Bp8bkEUB8awzbspIUeQ PCs/wLq3XtoaK/zPSJwlDvMaYRv1E1JWHUMXwHaXJsFdKOo9PkWnadPbZGyqIZs+sD8GwRrzyNm sbTVze2qgi3t7uzFObETRzHQfPJQA3Ew6s5RR+6WwczpI6CbhhBZs7CgCUyvW4uiIwgfxrT6qsY OhkOgWgJ7b0+H7eZOiCMEujQwoRjaEJcftOPgp6cmk3sD90Ccw3rrpaWFYhpcWa/iNn0JkXWQ/1 q7ysEYbAFhY2/DQwKZ6OLDoT58UUP5/G37rO2BAsb8lu49r/a+Vehuz3SjKAqNnPtadTSxje7Ia U2wsatzix/gPD79NO+lfBtB3rjT478+g9Ii5YKH9nB484KNfLxkPjMtoaoGjxmza0Xsvsvr6z5K ZK3OierbVewLFnMaOAnZ46YuTLBWs0WVkVxP6kK11CZJpK5jZf85MlbbcAR9cfVXc758EZlDM8q g+6K+ZXU30BquALpm5CHIceWGJmHyMhCutehLeqv6tE6eDoew944DVHKv8SS8Saqo7Su4d8mOiZ oqT2UoujiD8M2gg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 nfsd's usual fh_compose routine requires a svc_export and fills out a svc_fh. In the context of a CB_NOTIFY there is no such export to consult. Add a new routine that composes a filehandle with only a parent filehandle and nfs4_file. Use that to fill out the fhandle field in the nfsd4_fattr_args. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 33b6cd492e56..f8534288b2fc 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4184,6 +4184,39 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct x= dr_stream *xdr, goto out; } =20 +static bool +setup_notify_fhandle(struct dentry *dentry, struct nfs4_file *fi, + struct nfsd_file *nf, struct nfsd4_fattr_args *args) +{ + int fileid_type, fsid_len, maxsize, flags =3D 0; + struct knfsd_fh *fhp =3D &args->fhandle; + struct inode *inode =3D d_inode(dentry); + struct inode *parent =3D NULL; + struct fid *fid; + + fsid_len =3D key_len(fi->fi_fhandle.fh_fsid_type); + fhp->fh_size =3D 4 + fsid_len; + + /* Copy first 4 bytes + fsid */ + memcpy(&fhp->fh_raw, &fi->fi_fhandle.fh_raw, fhp->fh_size); + + fid =3D (struct fid *)(fh_fsid(fhp) + fsid_len/4); + maxsize =3D (NFS4_FHSIZE - fhp->fh_size)/4; + + if (fi->fi_connectable && !S_ISDIR(inode->i_mode)) { + parent =3D d_inode(nf->nf_file->f_path.dentry); + flags =3D EXPORT_FH_CONNECTABLE; + } + + fileid_type =3D exportfs_encode_inode_fh(inode, fid, &maxsize, parent, fl= ags); + if (fileid_type < 0) + return false; + + fhp->fh_fileid_type =3D fileid_type; + fhp->fh_size +=3D maxsize * 4; + return true; +} + #define CB_NOTIFY_STATX_REQUEST_MASK (STATX_BASIC_STATS | \ STATX_BTIME | \ STATX_CHANGE_COOKIE) @@ -4193,6 +4226,7 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne, s= truct xdr_stream *xdr, struct dentry *dentry, struct nfs4_delegation *dp, struct nfsd_file *nf, char *name, u32 namelen) { + struct nfs4_file *fi =3D dp->dl_stid.sc_file; struct path path =3D { .mnt =3D nf->nf_file->f_path.mnt, .dentry =3D dentry }; struct nfsd4_fattr_args args =3D { }; @@ -4231,6 +4265,9 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne, s= truct xdr_stream *xdr, FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY; attrmask[2] =3D 0; =20 + if (setup_notify_fhandle(dentry, fi, nf, &args)) + attrmask[0] |=3D FATTR4_WORD0_FILEHANDLE; + if (args.stat.result_mask & STATX_BTIME) attrmask[1] |=3D FATTR4_WORD1_TIME_CREATE; =20 --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 277BC3A9631; Fri, 22 May 2026 12:29:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452983; cv=none; b=u4Bu4/zkzvCzN37LqJIGxFmWt2pJwlONsNXl0H2TuBCZFaLguAilz1/5jQaPSAzCoMRFPFUzN3gp9g+WMEvOpCSDt7HpDY/Ni9W5oAboz2d3NDtrxmOcZcKkoNKqI24YbLMO3GpLtB8136qaYiiP24GQcbemqCaWEmI4jNUYctI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452983; c=relaxed/simple; bh=Tm88PYbTKOzA1m6/RvOrfrf+njGW/yUDKwdnprgqAUo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NM71D0zSB89/FgKAu4W99PKovpw6gIOSXugNO/EGZrzV+lFBrnobhS7EHGJ+sTaUXJcwOmNbZKEXlPW8RQOQ2RXnqld6qoU2kd8qgx2QKZGK45VlU2Gm0vDu0OBKkHI/BIuhCwVtxf9o0z4M+d84keNW5zHtKBjA8TtSLdjjpIw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UUGOaOuL; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UUGOaOuL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5D67E1F00A3D; Fri, 22 May 2026 12:29:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452981; bh=3Oi/l6/G2+8157KS0fYrmVbRBuFCb2KUekmH3Df2YEQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=UUGOaOuLmB/iEALzjBJiW7D/1zu4rbPaTGOZWaC07O4xe3BYHcsqDp4TikahJUjIf Rx6k7A/FSq6924usvc7E6SGLlZQ+7rp49o5NiYbDqLa1P35rXcVaCEkeVC6qVslzi0 GoSopdcYZeMPamIaIHFAGUINdby+o61P8UPOzU2/dTt9wS4QMxPVuCZjDEnefCBaje TPFJc3GQe6aaZLo4rIx4QOdjJZLZws20tji+422lVN1mep/PJDneLK7MZefxqRHD9G ol8+mBR+6IsUIFjRv1Q8zLlEWlG9HxMtfamjRfcjxeWaU6ROYLPopUZtuvcd282hYG zBJws3ayJ05zQ== From: Jeff Layton Date: Fri, 22 May 2026 08:29:08 -0400 Subject: [PATCH v4 19/21] nfsd: properly track requested child attributes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-19-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3821; i=jlayton@kernel.org; h=from:subject:message-id; bh=Tm88PYbTKOzA1m6/RvOrfrf+njGW/yUDKwdnprgqAUo=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwS8CsBjedkws2MRlmwps33Bvv2xUEEiqwb7 Ge4tOsQktGJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMEgAKCRAADmhBGVaC FUevD/4zeaiqpESoQKvPVUR215ADzzcmCL2Ayf0nP4QQVNjk4I4/DfsLbw2dUWUyNMnIi1DVH7e zMzSaq2TZfKykrWxkImtTxZGKGtrQxJwQEoEizPQsh6DPbbYbJlOqqqbX2Ib8oXRhkPnUGC56Tq 33YMcC+Z5mU+A++Js03rtv0SUJKmbJzuJjzV+o+H4R5q6QvDB37rPgt24rdShZb0Qf7C4kIAyeo 5raFbhmJQo7J64izCtPWMOKl8ybfJ78JPoYx0ejeasy/WEdddvM1qbsBwt1/U+hgTJqxqABma4h XbPknfF6ge7f/mQ4SfsBRQ1ungbu/zFYrKDJywwoDA/QlrGvU3rboaY9FnUQQ2Nc8U9VSUEVrCV xFr/QnHOzkFxdATRpPI1zPOT2/KXhL1vdwYfbR6pDYSk6DactfeMyaJtHETLX7364rRHSJBfl0K z850qfXYxJSu5jAWMZlBsFn0BRVvtjizwin6LLRguXvVdT9c1q333m4OSlpu2B0uPG4szy/L9jl FQ/Inm2aFpOX34a2nhmcrEBdbjNORyP34bpbA8CeKMyjKlvonSTk2hWb7/kxeG9fpnvJF1nEM3g xA8hkwAZ6HycWUAzzirUDYT0K7b9+MdLANMIKhwOeN+KnLwXCzgsjmmXpfRpFBZ6SA3FCMME4fn mmBKFMkajtttxlA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Track the union of requested and supported child attributes in the delegation, and only encode the attributes in that union when sending add/remove/rename updates. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 2 ++ fs/nfsd/nfs4state.c | 18 ++++++++++++++++++ fs/nfsd/nfs4xdr.c | 15 ++++++--------- fs/nfsd/state.h | 3 +++ 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 30f338f90acd..1eed8f23551d 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2568,6 +2568,8 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, =20 gdd->gddrnf_status =3D GDD4_OK; memcpy(&gdd->gddr_stateid, &dd->dl_stid.sc_stateid, sizeof(gdd->gddr_stat= eid)); + gdd->gddr_child_attributes[0] =3D dd->dl_child_attrs[0]; + gdd->gddr_child_attributes[1] =3D dd->dl_child_attrs[1]; nfs4_put_stid(&dd->dl_stid); return nfs_ok; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 0e7512046c63..90055edc633b 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9816,6 +9816,21 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp,= struct dentry *dentry, return status; } =20 +#define GDD_WORD0_CHILD_ATTRS (FATTR4_WORD0_TYPE | \ + FATTR4_WORD0_CHANGE | \ + FATTR4_WORD0_SIZE | \ + FATTR4_WORD0_FILEID | \ + FATTR4_WORD0_FILEHANDLE) + +#define GDD_WORD1_CHILD_ATTRS (FATTR4_WORD1_MODE | \ + FATTR4_WORD1_NUMLINKS | \ + FATTR4_WORD1_RAWDEV | \ + FATTR4_WORD1_SPACE_USED | \ + FATTR4_WORD1_TIME_ACCESS | \ + FATTR4_WORD1_TIME_METADATA | \ + FATTR4_WORD1_TIME_MODIFY | \ + FATTR4_WORD1_TIME_CREATE) + /** * nfsd_get_dir_deleg - attempt to get a directory delegation * @cstate: compound state @@ -9885,6 +9900,9 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstat= e, dp->dl_stid.sc_export =3D exp_get(cstate->current_fh.fh_export); =20 + dp->dl_child_attrs[0] =3D gdd->gdda_child_attributes[0] & GDD_WORD0_CHILD= _ATTRS; + dp->dl_child_attrs[1] =3D gdd->gdda_child_attributes[1] & GDD_WORD1_CHILD= _ATTRS; + fl =3D nfs4_alloc_init_lease(dp, gdd->gddr_notification[0]); if (!fl) goto out_put_stid; diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index f8534288b2fc..4fe697bf34e7 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4258,18 +4258,15 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne,= struct xdr_stream *xdr, =20 args.change_attr =3D nfsd4_change_attribute(&args.stat); =20 - attrmask[0] =3D FATTR4_WORD0_TYPE | FATTR4_WORD0_CHANGE | - FATTR4_WORD0_SIZE | FATTR4_WORD0_FILEID; - attrmask[1] =3D FATTR4_WORD1_MODE | FATTR4_WORD1_NUMLINKS | FATTR4_WORD1_= RAWDEV | - FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | - FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY; + attrmask[0] =3D dp->dl_child_attrs[0]; + attrmask[1] =3D dp->dl_child_attrs[1]; attrmask[2] =3D 0; =20 - if (setup_notify_fhandle(dentry, fi, nf, &args)) - attrmask[0] |=3D FATTR4_WORD0_FILEHANDLE; + if (!setup_notify_fhandle(dentry, fi, nf, &args)) + attrmask[0] &=3D ~FATTR4_WORD0_FILEHANDLE; =20 - if (args.stat.result_mask & STATX_BTIME) - attrmask[1] |=3D FATTR4_WORD1_TIME_CREATE; + if (!(args.stat.result_mask & STATX_BTIME)) + attrmask[1] &=3D ~FATTR4_WORD1_TIME_CREATE; =20 ne->ne_attrs.attrmask.count =3D 2; ne->ne_attrs.attr_vals.data =3D (u8 *)xdr->p; diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 56008234b700..461abcee9e6c 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -284,6 +284,9 @@ struct nfs4_delegation { struct timespec64 dl_atime; struct timespec64 dl_mtime; struct timespec64 dl_ctime; + + /* For dir delegations */ + uint32_t dl_child_attrs[2]; }; =20 static inline bool deleg_is_read(u32 dl_type) --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 B76183A5E9F; Fri, 22 May 2026 12:29:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452985; cv=none; b=C/9YqmDza4QZsQhVrrmZntGps/6qdaMJZWya9QA0XF8D9D3Rfjm5+CBv7NnL+fgT0r9/nc+B2fI/X6BucgC+qYwDUsenLlO7TFNyQjisAnE3xdb00azQBg52Mj68OKfW+KmEqmQ1eEO0JP0xjNXVj55NOtoGypDJZ9UszFckl+c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452985; c=relaxed/simple; bh=NWvvem3CW6rxu7DKwqXTlkFQFX+XJDKIa2pHqduYekY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GtWHOpipZUXaSNmY/9dhSUfMMASGEBb2vN9NsmKRudPpnU7EGFd0A3VRHGNxDDXt8CdF7nhf8aX5tgRV51KybYuAcO7LnUa9P5GRMyzeCMgyBYU3i+Br4wqd/1wC2NQl39CyaZbHHB3Re+0ZMc/bvCwimTJ8BL/wIpk6XOiwMMA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k7X4unIO; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="k7X4unIO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 176711F0155F; Fri, 22 May 2026 12:29:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452983; bh=r83rwBwe//1WtoEhr33QAfdCCDq5UmpT/2oTOLquYB4=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=k7X4unIObTLQq0J+xcUUXSTe/gfLT1IJwObzz2wnv60yhXpzMsfA1L/fqqCwxNCzb 2AKR5fsB6zsZz6I/vRMpyAPnR1hNMJ5olb/Sz35bhls0vHKtuRQ8UrcCQlmuons7gv XQ26sq7Zpm5NR+bs4WpfceKvZn/cX11+4J7xEH64C390cgDa2NkQNtlmCSEQfSO/tY oahAhcUKepTREoSAQuiYeicD9ORYppjaCzc+NeRn1fEOo4tafKq02BFsbS2g4ssXC1 MvY73Wc7RVlEVzkhXUYTi3lZtXMVPgXuMtyuJyKMZhn7vY2k7A00qxnuDPuG0sQNW+ tP/r2R6/8EtXg== From: Jeff Layton Date: Fri, 22 May 2026 08:29:09 -0400 Subject: [PATCH v4 20/21] nfsd: track requested dir attributes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-20-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3281; i=jlayton@kernel.org; h=from:subject:message-id; bh=NWvvem3CW6rxu7DKwqXTlkFQFX+XJDKIa2pHqduYekY=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwShHsJ8URiPBlb6HOuNmPEYMJGlV2gIBZs6 SlokQGq8+6JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMEgAKCRAADmhBGVaC FWiND/0T1Z33y3Yd2JdtVJtcqmYoT6XaykYthLh1kXZz7J3GUk5q1GNT22haIPz/d8kmUxrhlTb DU1knScvOtwT2Z5ab+xq1q23LzULAczoLb/Cr43d1JWkh+zA10/J5a4wpneY/Z7xA9NwJSEH5ek OihvqeXLVMXAHX7/05vaSCigJQLzFWEFlz7k6Z/faWbVS4OGCKYXJbF0hnRDQrWRUN7cM/S5y8M fdRGQyk0YlITwEJx25s49gr9ztkBVL6r3iTU7NLt9jp81w6fDsKVFLCz6TXdyC6Wxn5iARulCDo z/dcP8HLrXWURFJQAq08XVJTXeM2J6AyaPxpmII0+1YVmPJkGI4COPLrmqM2BxbRecq8z+IfegK Q05Q4uTS8cVgpzR0d+IkkoJSvFzJnpX71mJKRM25owgmDfCXFH6gNT2EoLvzKmziFM/IyXs26BS Uomghpm2hs+NStAmhpQf9QrgZGOz0GN9aCJ7GLOy0pju59wjixZQvpBUxzANp0ex2MMeGuSmCXX 9rh7/GIfYTZ0j8caMuf1ItQjhj1cN/R6AES29ZxHD0xlN+GthxiDJpVU27jk63J6FpGRXqCFM7O 9qIjMZZ09s0MDewvvqTlbt/A0FiSmaxJqbegOFPmT2bYCY2XdVBV/KNqD/MfhgTlJc903CVO+ME myzU6iYKS2fhOZw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Track the union of requested and supported dir attributes in the delegation, and only encode the attributes in that union when sending add/remove/rename updates. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 9 ++++++--- fs/nfsd/nfs4state.c | 14 +++++++++++++- fs/nfsd/state.h | 2 ++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 1eed8f23551d..43da73a537ad 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2521,9 +2521,10 @@ nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_co= mpound_state *cstate, return status =3D=3D nfserr_same ? nfs_ok : status; } =20 -#define SUPPORTED_NOTIFY_MASK (BIT(NOTIFY4_REMOVE_ENTRY) | \ - BIT(NOTIFY4_ADD_ENTRY) | \ - BIT(NOTIFY4_RENAME_ENTRY) | \ +#define SUPPORTED_NOTIFY_MASK (BIT(NOTIFY4_CHANGE_DIR_ATTRS) | \ + BIT(NOTIFY4_REMOVE_ENTRY) | \ + BIT(NOTIFY4_ADD_ENTRY) | \ + BIT(NOTIFY4_RENAME_ENTRY) | \ BIT(NOTIFY4_GFLAG_EXTEND)) =20 static __be32 @@ -2570,6 +2571,8 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, memcpy(&gdd->gddr_stateid, &dd->dl_stid.sc_stateid, sizeof(gdd->gddr_stat= eid)); gdd->gddr_child_attributes[0] =3D dd->dl_child_attrs[0]; gdd->gddr_child_attributes[1] =3D dd->dl_child_attrs[1]; + gdd->gddr_dir_attributes[0] =3D dd->dl_dir_attrs[0]; + gdd->gddr_dir_attributes[1] =3D dd->dl_dir_attrs[1]; nfs4_put_stid(&dd->dl_stid); return nfs_ok; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 90055edc633b..4a078b51506b 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9831,6 +9831,15 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp,= struct dentry *dentry, FATTR4_WORD1_TIME_MODIFY | \ FATTR4_WORD1_TIME_CREATE) =20 +#define GDD_WORD0_DIR_ATTRS (FATTR4_WORD0_CHANGE | \ + FATTR4_WORD0_SIZE) + +#define GDD_WORD1_DIR_ATTRS (FATTR4_WORD1_NUMLINKS | \ + FATTR4_WORD1_SPACE_USED | \ + FATTR4_WORD1_TIME_ACCESS | \ + FATTR4_WORD1_TIME_METADATA | \ + FATTR4_WORD1_TIME_MODIFY) + /** * nfsd_get_dir_deleg - attempt to get a directory delegation * @cstate: compound state @@ -9900,10 +9909,13 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cst= ate, dp->dl_stid.sc_export =3D exp_get(cstate->current_fh.fh_export); =20 + dp->dl_notify_mask =3D gdd->gddr_notification[0]; dp->dl_child_attrs[0] =3D gdd->gdda_child_attributes[0] & GDD_WORD0_CHILD= _ATTRS; dp->dl_child_attrs[1] =3D gdd->gdda_child_attributes[1] & GDD_WORD1_CHILD= _ATTRS; + dp->dl_dir_attrs[0] =3D gdd->gdda_dir_attributes[0] & GDD_WORD0_DIR_ATTRS; + dp->dl_dir_attrs[1] =3D gdd->gdda_dir_attributes[1] & GDD_WORD1_DIR_ATTRS; =20 - fl =3D nfs4_alloc_init_lease(dp, gdd->gddr_notification[0]); + fl =3D nfs4_alloc_init_lease(dp, dp->dl_notify_mask); if (!fl) goto out_put_stid; =20 diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 461abcee9e6c..62a5fe3f6cc0 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -286,7 +286,9 @@ struct nfs4_delegation { struct timespec64 dl_ctime; =20 /* For dir delegations */ + uint32_t dl_notify_mask; uint32_t dl_child_attrs[2]; + uint32_t dl_dir_attrs[2]; }; =20 static inline bool deleg_is_read(u32 dl_type) --=20 2.54.0 From nobody Sun May 24 18:41:13 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 B78EE396B9A; Fri, 22 May 2026 12:29:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452987; cv=none; b=NjyxdpyXGYV+lBIq3tsrFIFwEV+gYwhncgJtsUCS8DwAi71A9K54FdT3kqu0rcKqg7mSeoSYeQ/IR0z6vIGwM8vqXkMgNSx8FICqiRHAPDhloONLmX3fnS9hDvcaH1cVdZbCF7AU1HYKWUrSU3sNiCSPQriTjQ1PJUOTDnXzNw0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779452987; c=relaxed/simple; bh=n094Y6iJ3spWbyVj9NXLGKhtNg67cBauAd1DvKPlUTY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cxMu6lQt6koQ+8Ut9KeVq2mYlKTh+1TLgrpskq6TalcEMOl4Qi0FcHdfmMG+d06t+SI+Wm11igRsOAoBI/4FFv+/XmroxJENiPhUT5ryCVs7LIQSC0rJcBl7TtuXTsqydi/qCCBgRRPgoYtgEGDVzZd0VohalLootlrSINBdKLg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lftIQpqQ; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lftIQpqQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C2CAA1F000E9; Fri, 22 May 2026 12:29:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779452985; bh=bWyWQkGX486MPJv66TllLqijhqa59fSqHuKYh3opB4Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=lftIQpqQtVuYUtUe2lX7etHBqXQ3dNhGxA2ymRYJOYZMWiYpS/8uszccJVVW+RkVW 5sGnqzNdQF3nUF/rZBIS0GMfCWvzm5fq0ViGclhXZrvYENllYjqURzNvcYdqZPRgfI TsiYV+qJa+1ROnBKm+m0uAR158HAeZiq3MuZUeZm9ol3kDh70ddR/u7fNwvIeeORBX 0ASQNdDRpYsFdzjAyAq+uByOCVTLduwcsb1H/w2SVwTTy28/upjQciBFN1FAjIEzEX aq9uK15Rwo8b6MDvMz9BrV1x57qYcMSXFq5JWmxexMF9cEfpaUy5jsC6fYen+X2Amz X+TzUWh5KZe3g== From: Jeff Layton Date: Fri, 22 May 2026 08:29:10 -0400 Subject: [PATCH v4 21/21] nfsd: add support to CB_NOTIFY for dir attribute changes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260522-dir-deleg-v4-21-2acb883ac6bc@kernel.org> References: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> In-Reply-To: <20260522-dir-deleg-v4-0-2acb883ac6bc@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Alexander Aring , Amir Goldstein , Jan Kara , Alexander Viro , Christian Brauner , Calum Mackay , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=6108; i=jlayton@kernel.org; h=from:subject:message-id; bh=n094Y6iJ3spWbyVj9NXLGKhtNg67cBauAd1DvKPlUTY=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqEEwTaTKb0Q8gBI05oUpUIRLP3Up50YMyqYWJq aoetENq7KyJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahBMEwAKCRAADmhBGVaC FRerD/4sXAbqO20EYs5tLpzmsVsSlqkOL6oM7+qPEDdOXLP8HM1yMuBfjo2Lej6nnaCkxGrkgmY a79V7WxOJ9M6ONzIXhDffgQd7qi7QX9PJSYeTPYOfUv7IhSKxY/3m7lpjCFIt235gk7E8SwT/v5 PGSkRQiPnxfiCOu3tXloGqkryzR/jLqZLGTKIo5tBUoXeZUOZu8/41tb20HTNeO/n97z1aHVFtx 4jSZ9mLyVX9rjgKMIGG/asPbLtqL81VNRgCCBwwSxr1XvOBfL1fGe4pA/pyLEIWJVSq4GYj6tCP f5sX4d6doQwPB/AEpi30VUg5p1S4GKHhoZn4VvWpnhMqHjIRD09HyUXuOJzjOJib9TARNh0zkTZ nbGBL1o+rtmBbiqjHm0aaSbKyTTgRa9I6jmgXMajPgvrKSgWhmv7mhScjTrrT4+/i8nj3B4S39Q IShyN7V3DxtlsP+SSM/6HXRL3vPNo/8BIISXzEaN+nnnKbCTk/CLbAr9d78bIg8z3EgBGJxHgqH 8rOX6OawNHJZlupkGVixSWrJ9694cmtU4ssCpBt6g71G/C6C7BAeYczcFKLMZc6wSe0ri6mnHhB 4QH8vhH/HIfDok+SkqBpt+xnG4zxEdHxbWSjjwEOO5BOwSCFeoMGHCZaapPTwc/EexD6QoxqF6z nO+wAEh6NldwVsw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 If the client requested dir attribute change notifications, send those alongside any set of add/remove/rename events. Note that the server will still recall the delegation on a SETATTR, so these are only sent for changes to child dirents. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 25 ++++++++++++++++++++-- fs/nfsd/nfs4xdr.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----= ---- fs/nfsd/xdr4.h | 2 ++ 3 files changed, 77 insertions(+), 11 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 4a078b51506b..34728aa3161e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3487,10 +3487,15 @@ nfsd4_cb_notify_prepare(struct nfsd4_callback *cb) struct nfsd_notify_event *events[NOTIFY4_EVENT_QUEUE_SIZE]; struct xdr_buf xdr =3D { .buflen =3D PAGE_SIZE * NOTIFY4_PAGE_ARRAY_SIZE, .pages =3D ncn->ncn_pages }; + int limit =3D NOTIFY4_EVENT_QUEUE_SIZE; struct xdr_stream stream; struct nfsd_file *nf; - int count, i; bool error =3D false; + int count, i; + + /* Save a slot for dir attr update if requested */ + if (dp->dl_notify_mask & BIT(NOTIFY4_CHANGE_DIR_ATTRS)) + --limit; =20 xdr_init_encode_pages(&stream, &xdr); =20 @@ -3504,7 +3509,7 @@ nfsd4_cb_notify_prepare(struct nfsd4_callback *cb) } =20 /* we can't keep up! */ - if (count > NOTIFY4_EVENT_QUEUE_SIZE) { + if (count > limit) { spin_unlock(&ncn->ncn_lock); goto out_recall; } @@ -3551,6 +3556,22 @@ nfsd4_cb_notify_prepare(struct nfsd4_callback *cb) nfsd_notify_event_put(nne); } if (!error) { + if (dp->dl_notify_mask & BIT(NOTIFY4_CHANGE_DIR_ATTRS)) { + u32 *maskp =3D (u32 *)xdr_reserve_space(&stream, sizeof(*maskp)); + + if (maskp) { + u8 *p =3D nfsd4_encode_dir_attr_change(&stream, dp, nf); + + if (p) { + *maskp =3D BIT(NOTIFY4_CHANGE_DIR_ATTRS); + ncn->ncn_nf[count].notify_mask.count =3D 1; + ncn->ncn_nf[count].notify_mask.element =3D maskp; + ncn->ncn_nf[count].notify_vals.data =3D p; + ncn->ncn_nf[count].notify_vals.len =3D (u8 *)stream.p - p; + ++count; + } + } + } ncn->ncn_nf_cnt =3D count; nfsd_file_put(nf); return true; diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 4fe697bf34e7..2143fb6d5e3f 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4227,11 +4227,11 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne,= struct xdr_stream *xdr, struct nfsd_file *nf, char *name, u32 namelen) { struct nfs4_file *fi =3D dp->dl_stid.sc_file; - struct path path =3D { .mnt =3D nf->nf_file->f_path.mnt, - .dentry =3D dentry }; + struct path path =3D nf->nf_file->f_path; struct nfsd4_fattr_args args =3D { }; uint32_t *attrmask; __be32 status; + bool parent; int ret; =20 /* Reserve space for attrmask */ @@ -4243,6 +4243,9 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne, s= truct xdr_stream *xdr, ne->ne_file.len =3D namelen; ne->ne_attrs.attrmask.element =3D attrmask; =20 + parent =3D (dentry =3D=3D path.dentry); + path.dentry =3D dentry; + /* FIXME: d_find_alias for inode ? */ if (!path.dentry || !d_inode(path.dentry)) goto noattrs; @@ -4258,15 +4261,20 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne,= struct xdr_stream *xdr, =20 args.change_attr =3D nfsd4_change_attribute(&args.stat); =20 - attrmask[0] =3D dp->dl_child_attrs[0]; - attrmask[1] =3D dp->dl_child_attrs[1]; - attrmask[2] =3D 0; + if (parent) { + attrmask[0] =3D dp->dl_dir_attrs[0]; + attrmask[1] =3D dp->dl_dir_attrs[1]; + } else { + attrmask[0] =3D dp->dl_child_attrs[0]; + attrmask[1] =3D dp->dl_child_attrs[1]; =20 - if (!setup_notify_fhandle(dentry, fi, nf, &args)) - attrmask[0] &=3D ~FATTR4_WORD0_FILEHANDLE; + if (!setup_notify_fhandle(dentry, fi, nf, &args)) + attrmask[0] &=3D ~FATTR4_WORD0_FILEHANDLE; =20 - if (!(args.stat.result_mask & STATX_BTIME)) - attrmask[1] &=3D ~FATTR4_WORD1_TIME_CREATE; + if (!(args.stat.result_mask & STATX_BTIME)) + attrmask[1] &=3D ~FATTR4_WORD1_TIME_CREATE; + } + attrmask[2] =3D 0; =20 ne->ne_attrs.attrmask.count =3D 2; ne->ne_attrs.attr_vals.data =3D (u8 *)xdr->p; @@ -4383,6 +4391,41 @@ u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr= , struct nfsd_notify_event * return NULL; } =20 +/** + * nfsd4_encode_dir_attr_change + * @xdr: stream to which to encode the fattr4 + * @dp: delegation where the event occurred + * @nf: nfsd_file opened on the directory + * + * Encode a dir attr change event. + */ +u8 *nfsd4_encode_dir_attr_change(struct xdr_stream *xdr, struct nfs4_deleg= ation *dp, + struct nfsd_file *nf) +{ + struct dentry *dentry =3D nf->nf_file->f_path.dentry; + struct notify_attr4 na =3D { }; + struct name_snapshot n; + bool ret; + u8 *p =3D NULL; + + if (!(dp->dl_notify_mask & BIT(NOTIFY4_CHANGE_DIR_ATTRS))) + return NULL; + + take_dentry_name_snapshot(&n, dentry); + ret =3D nfsd4_setup_notify_entry4(&na.na_changed_entry, xdr, + dentry, dp, nf, (char *)n.name.name, + n.name.len); + + /* Don't bother with the event if we're not encoding attrs */ + if (ret && na.na_changed_entry.ne_attrs.attr_vals.len) { + p =3D (u8 *)xdr->p; + if (!xdrgen_encode_notify_attr4(xdr, &na)) + p =3D NULL; + } + release_dentry_name_snapshot(&n); + return p; +} + static void svcxdr_init_encode_from_buffer(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p, int bytes) { diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 62ac790428be..805c7122eb93 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -973,6 +973,8 @@ __be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words, u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr, struct nfsd_notify_e= vent *nne, struct nfs4_delegation *dd, struct nfsd_file *nf, u32 *notify_mask); +u8 *nfsd4_encode_dir_attr_change(struct xdr_stream *xdr, struct nfs4_deleg= ation *dp, + struct nfsd_file *nf); extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *, union nfsd4_op_u *u); extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, --=20 2.54.0