From nobody Sun May 24 18:41:31 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 4EF6837BE80; Fri, 22 May 2026 19:42:32 +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=1779478953; cv=none; b=nR8QO4Rw7nGJtKN3stkimqlWq9XCfWe7Ej8q8abx1JDqeswde+ycs2DQFWVmRjHeLlOg0lSzRKn8karMZsMANmKYBj5APRQB/1pYvy0rjKUZJBItan7iiD//4goyN3R8wXTz5W0Gmb38L1Hh+UYl0rKAg5TKBpkfAa/diBQKew0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478953; 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=uvewBs7QKQ0Xl3qDYbTzuJsz7+ncHBEmKEpTE8xxzYOC2PDawzO2iz7lQN6JSDesyGBFAXjCNhW3PmyCh1K2UDG0Q67r0no53xkdH9NEojRWjFtsZA892aFWg5skIL1S6cvN04gToYz86SzvluIlJFdDUvgTOBlCewwL+eQVEbI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JDTolst7; 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="JDTolst7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 48DF11F00A3D; Fri, 22 May 2026 19:42:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478952; bh=tS3ewl/RblzPq0s0br2Ku7A8Mpy7aLrtToStoyvDFrA=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=JDTolst7Da5QxDQrmw08wDSUlzLgQNjZNt2IB5YB+oSWpbqro4fCt4xfbR+HhOqp7 IOSTDCbOKhXsgscKCslOo5UOsRPLCNSsEerU9wEmpmvIu/M4wxnkiDQJDVn3VdIL7B jhy2r4KXCNSX7pUyoQ6wiFWMziR6SGYzv2nArVI6mEAqKHNVTH4pJzS4Sdi0P6JGJH F0mO9x1YCyBniIxv6BbLz+0HA2/4/s45glzcqcU369dQGHyC/gIzyCk0tk3/MlzWZu +knJUzzQ+fqgaeHW19i7N82G0OWo7VsEC9IaumYmqRFPafI+yvV6hdNbHllK3VpMNS XFHyh+LWJ8x2w== From: Jeff Layton Date: Fri, 22 May 2026 15:42:06 -0400 Subject: [PATCH v5 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-v5-1-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGciCVEOBfhd6IsQqcKVVVVlC9dE5yVsKEy4 TdN/Cv2SyCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxnAAKCRAADmhBGVaC FRZVD/0Uwq6bdtD2qIN7pwQLS2CgbgvUmw4+LgbHqbhbZdim4yghqWYGmeNOq4BH0YGcVzv51VD sgRfWDSIwCal5ObWni2aGO5AAMgUomYcK8v+eJikkIKMyssEEDv+V6L6/TZeQRgcVPyUJZcbMKM FLdF/bGkj7wbZRy/b6f/6SwRJougWS8XIs1rVwHylg4OlhrYYW0BHqq+T+aXubIU+OzAft0aAdW y08JD3lQqBL+xTUyxX7MJDyk4UZt9UUSkFuLvOP06dmG17pk06oMjCcF8uQhabl9/TiqnsLR80Q YklvpQ8iuTlbz0iBF4MrfMgAKdSJk+PhPLgpJnTJnD3qOvrod5XWHUkmrL4Ymsr6+te+7jDfnfv I60ObhOSKGdcy31b+7njpFFpnGZ78fVONz+q2Pvj4Mxuh3mHw8/Zrsdig71SA0mWEFo7u01vxaa MnjRV2Z+HksEOZNr4ZvLEWUZYu8mui9Ztbh7lgqotZh0YYDlFYgYBR2jYR5296BlitV4FVD+mK1 kx/QzhyQBwXHxn/rmPcGK7iRK73KcH40PEeJjQ3HESTgchAjusKC3X88nP5KkhhMCvKdq/6NZXs droNeTsla+fWlnXCQIgjg7C+6Hk6OxuxDY55j9ziZZGHfEtTTEc7rClqf5Vxr4cnCQzIjlJqIpY BG5O7PcjBnqH7pg== 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:31 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 A426837D108; Fri, 22 May 2026 19:42:34 +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=1779478959; cv=none; b=AWK+CdXKYtG5zSlFpscCee4JZySEJ6DK0q3xFiWvn+UG8/dA18Pv6cXSyHkAHo1I12HTxyWrcB0AJXxYG8nSQOWuE9M3rj9Bna+Tbfrc9xlu5oWRTbVcSBWnjxQ+5JJeERvW4+xLHuPlgIH2A73JqlgSXtRw2ry0MsqwGdaWMMM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478959; c=relaxed/simple; bh=FRm/TvGa6QnyAkILHjmYgMZnO85GPEg6VGGCZqnV5fQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tf7grAaaNffO1ByAbdXMT4gGoDGKy+JPyMacPHIxI582p4zWUAGGc9Hm8+1pgVeYuN40eYkFDzZoDTezABbMLZ1thYT5zaxZRUSQN9IYJ3ZaTKdjxCz3ZDMFKpuWmyeUl4BbRkpceSndbdOWW1a+zdddComfj3Aj9SzPYui7YD4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ogJomQWP; 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="ogJomQWP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 38E111F000E9; Fri, 22 May 2026 19:42:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478954; bh=ILQxohJxsf3Mljx2/JAsrn32es/mAXwooX7eiKkh+FA=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=ogJomQWPkEaqfGCbCQFP7MUwaqftoT+ztfFDxIYMKR/bAra6OdR3JkL0ztwg4jCt0 IL2tctaad8G/yTZXFE6R+jz2ZSzYLEOi9HIxO7cPnBtbdztiaa69vkfkaSluG6q0OB ru+ULSoKHYGlSO39NZhT2G12A0SAm+yspWtU2sfL5ZsyAjxFO9eNt+6ZOBDNVAZWui jU+3rJJFNMFnOLkt3p4m4PraObSfqyRRNL6zl6lRAgJaEYuZKRmC6u5jP1Vc34oNx2 kFZJLlfon6nlF+M8Nl8GTfMlaA/Cgqb/IPu8IazfWCnSX2xMCUes9kJ9u2NgprIshe Pc7T32+jRhczA== From: Jeff Layton Date: Fri, 22 May 2026 15:42:07 -0400 Subject: [PATCH v5 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-v5-2-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGcWF8d/4S9pPJtVoz9A/BA6cN7QAauAtwtx yRxazQuqM2JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxnAAKCRAADmhBGVaC FZvLD/92ujs2+HabRVODoY2GloBtVV0nVcasEGm1+SrjlGvG292uP196vvd47oOQQFTVTwbkJH+ nTF515ihz314HRsnuelM9Q3rF4+A+JlT7lWnlRSZTPSa4+pN01/DAW1D4W/2FOuRA6T0wrQArV0 one8xQ0f+79HpMczjWryfcOfsqrrTE8yRQVqJxVXJ8kyyovQo8U+5PNvjBKaDseYLEIJ7wm/xjV WtwgFxTYlEwCJdB88XbSeWyKJLdUTYFV3G2bL++NFDika/AhLrjudDf4udcJcwKw7QUamZQdLZ/ JKbkoT76uUPzoCN6Tzj1gdUeLP0eUFtDO/WZlSM+Wpf7NkMrUapftRJkN/zELG8nEkYJp8iPMu5 YbM+AWgo69U9SbKG9BWxrrNBD6M/sc/tuq59jCZyZYx0tKZTjh3WZHmhO1sHQrSIb7cgeagmZFD zp7Z1NGI0eNrfOTNSaBABFPEaXAon3ubAHwYxDP3BM2An1x6kkBkBB2AxR4W+BMBfdqNKPaw/8N 58jbz7+wye7ug6k1HFCHAeYnSCzenTJ9IaLjeI1YOh3jwF/MB+FQ9XZiX20xVpEWP7N0QmMAmh0 vYxIdm1PBkXv6NCCB8IUKyHpwOmM6Opozg+7Mk+bt4AkCHe5eaQME1YWlvHu0dYxEjgvUFWwYHS nOvRUAaQa6kJlCw== 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:31 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 46B70379EF0; Fri, 22 May 2026 19:42: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=1779478958; cv=none; b=YwAHw4kx93o3rPUIlI/KVSg5gfxJp8BnAk40ZtZKqPDIZQYooxyG7BYUFMbLg0IBxY43EKboE/8vDoVE7ozyKKchtd9q2mxLOhxt2qrrjTetDVNHYvQvcleyn1sLNKl38MCLA3FoWJxqRja+BPP4hCL6sZCsDyWiu3sXvsM2xa0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478958; c=relaxed/simple; bh=YLh4/lMM1FLFsNW282HugdeM6AzL2tOPs8cUBDQeTEU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TZTF5x5r0m2JcaNY/WbJ/+uBe07S7LKq09U93+XMrAHEH692t/GZMrA9j8WDwp5BzYjiA/REt08dPkudGCNbESkIk3BomrJYNra4X+7SGvKf6CTPWszsGdfnrb/jbu3J5hCkjISl487zJRYS9JqcCM4X9GBVR+ftGi0ZX4TRG7U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=O72rg2Hs; 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="O72rg2Hs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3F5801F00A3E; Fri, 22 May 2026 19:42:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478955; bh=aAgM8vwRcWxiJmuLj41yAuRh7mP2E+WvonVFr4ezXks=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=O72rg2Hs8cS97Pbbu/JwXVWsax+wNwwkk1mK12Gl8Nu3WTaAsAhZ0PaZObGvUDMSe dlpAgcRFXBQS74Q9bJLKjXFAnpPsQO/OJqnSsHMHc2ua4fb+t0l3F7CvUQ69q7OsEc 1mdrLGH/BxGTGgkn7GUOqMZVyABpzWG3IXdJpcdhvgunpc0N9/aOZFrh0MoxXPS+ZY l+Ma4kPpzNMmQ190HJUfk7cGu7NNcd39w5HxDaEBC+kNoWGgSDzWJOpB46RWlSo5XG MGrGYjdsVjZiS5GUlPZsc/yVnQZhv39sj5wEXVdbxUMM00pSnQASvalrg1P/8L/VHK zkfRwp5noLp8Q== From: Jeff Layton Date: Fri, 22 May 2026 15:42:08 -0400 Subject: [PATCH v5 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-v5-3-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGcbcMON5xMxgSGdCKQ1MohqDCBtlHf6EA3x akYvvz9szKJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxnAAKCRAADmhBGVaC FQXyEACgqvP2mfBMi74O1rYTMcO64aW1M3TFeF4QP48zHscMLpZNq3V6iNn+QQIUQt52DaU5ZXa KjRKOblt8BKYz61OyEj65T0RgE/cLBs64IBNBTwVkmvSROswTWIBEk3FaiUWYhlsOgvJJ2DSkgB /90lmKBcohg7ynP3DgUa6kt8zUeQ5VDCUME2I26Zi9R/4xzy9M2iuy8ol71/OvO6u2B02JBLMtl 81yVSie/2CLgXPyg8evsLb4vDNtmzKIFI2Ojd3rbA6qdZEu0dnVYR8I4XhuKxcoY6UMtBWY2GRM BOfjICIV0pe10nvrmd4qS07yAO4zJ/RtbkOACjRSHjhhwBItjTpJepFm1/M+l31DUVgf2WoKINg HyYDXOvCVmDHKpdMZ8f5ix0/awVazG4XrmURU3J+gnDBUoufPCKzV1ldaifzTKm/b5Ss3FIuO7y B7wj/6PU/6vj/dWic1Ozb0CDKa8uNKNsaQPb9m6J6cDlRHdN+TM8Sbhg0JLtPAwmO5LX3fdg4Q9 JTOPisncEVfHYZlKNsU2QbTEFwMS3ttj2VhX4YsWJCqc6nUo4qy5SrHsXS6iassZ5gT9d5kVCO2 mdyvfC/5lFGgxAcipmfDJiiIEdL5sjruFCmYE9oplXnzD+kqZZjdmhFOm4DVjujE1m6dsmxUrnN Xnie9QNqEjcd6aw== 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:31 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 CF68637DAC2; Fri, 22 May 2026 19:42: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=1779478960; cv=none; b=gNOBE6dXfRBeANF/GLFL9496Rw4wi7C4EHB0N5pcmhnDQzlWaw88r08EKomTxPgu58wbDFzQqw9jjBnrZRZYENd8Teeaa7uu4HVl1vp0is/14KsBSWuB1ly+1L1mEvgb1Iqv3ipoKi3vlg9zX4vAFo7erFd0nPQx0IwTmSMRqzg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478960; c=relaxed/simple; bh=6+xgS9Oi//iUZD1ri3viy4fOOkWtg6yKfKkrsgbZtwo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DxAmQm6rhHYpL15/3IIHo7N3XI/V6CKdBNZeXZlnkYDGNgjqgbixSI8t0urPGj9GZSNr4K9fQMzbtfBIoOumAml32G2XOmmddAd0ffDzc7LhZgr46J8AMaOkf3sYoc+q6ZR7vm+KQBrH211NzanDTuypuVzQQ62ks1a9p8w904Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gaGbHw9u; 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="gaGbHw9u" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2EE8E1F00A3D; Fri, 22 May 2026 19:42:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478957; bh=yn+E0MiyGHjI4tTcZW7VzxHDKSKAvs1i4UMk8wxbinU=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=gaGbHw9u7brDFj7avc7wDzaPMTRPI39HDoedRCPYSRitcECMKChVIHC8zEosH7b04 SUX2k5ACohh9GaA6Q1FLndnZQzBp4Jwxz0GsYc1T+Jqawlm3AN5VU7dwTDbh8tNr0X hhh7U+lf+CEpiaXglD46rFXkvJeobM06vpkArBF22T5olRg6DroWU0nlpD1CX1o4Rz LAwuJxpcHsjr1ttW1YFnu65ihqzo1E7d6EBeIyPXaMiysYuzf945tCnSp15uisUvPi Vp+A3VH8vH3IPK692+cY+RZny4uDX0pdNtAhRrbXhpdbub9/8WZdN6HdbRZe5zvBHf HpeQ4izYdDN8A== From: Jeff Layton Date: Fri, 22 May 2026 15:42:09 -0400 Subject: [PATCH v5 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-v5-4-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGdIfAeqY/TeCUSnSt3PnsVR37X5WfEtjz61 p72CTTa3qaJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxnQAKCRAADmhBGVaC FUStD/4hmSTwIH+z8GJlkcFPnFpSQtdWtAWO6vIqe4KSvNnvDu4LTCC5syJVuGvdayenSHY/Vxp tqE2Itwm3rVoOkwFslBewOmbEKQIs8QkrWDaAr6gDzVvK0268W88ncFItEkZ09xc+UA0uOL8aso cy1Fayyy4Z2f8tj4mgFqb5XP8sISgOcuLcBc0v6/f0RcsKO+9BQOTZ0kLpZHtpkJxhJqZDplVF5 o7zTLxU+nB8iVDwbdzZhJg6iEj6w0hSOOWOBcchLnKd0e6dw29IhmWi60GQGOYrJeuqz66M0hc2 pplEFM4fLQ1j9Jbwi73iTqi9nTd1lFP82/y8l3ZGTLaGcdIBwJco25zTHL05f6mkyYPbYFNtJQ5 cyMcseaGY0jR431hBESIH7/h7/l1291ziKP92wnZFPd2O51tzpBAEEgZ2zMsiKJ2FFKQw1AGjMN izX+XiBn3j0yJ1FcWJmmL7d87IosPAn97UJTv7rRhDG4I5qqufxeHwIAZh1fUdVum4rp2QTA02f fik5YzsOxR+qJeGWkoB6gbBlCuXz1a4htO8sXTodQN2IEYQxXVY4gx/z63cnqQ3uZ+NxmLSb4/G 5mO8eIFdrEwqs1sVPdooAfS8luY0f/iGJViaB3utZ0nvkNaK6ABTnTKDXr3t77g2Ac4leSVyZcL cuqwxBGYgFnd15w== 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:31 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 9F89037DAA3; Fri, 22 May 2026 19:42: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=1779478962; cv=none; b=Ch1vn9Ks49BltW/5yAz7k3eCuRpw+OfRAYZZVeMvqvKCjPZViSRINm2I+t1G8Me5cFUJTaJDaOL6YiJtSY7Z7LGpXx5eWxNkm7GIoQA7W6uXQ++p7xs03UM8jHeD5tut/pH4DeHCspQuyzLzCk3bu8Ic+DH1ZWKVI111Zp1I8kE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478962; c=relaxed/simple; bh=qKZ8zjvP2Xs35BWr9tiO7rsFDru5X9fTbNx6jHh/zrc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PvNfg+GN2Silasj8eFC3fTBBzFTiVgWfN1qq9E2TgnwYRl4ArhQSd51x6DTLG8LEkc2JTzBt8nXatK/jR9/gORfOzEiDaoN9VItfNXcmN7+y7nzuB7jZzuNNTge81wFgBsODI8m8ZVmQ6MQbVm+LvVNUNSTd6ntBRtllalBIXb0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KKKLSSAt; 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="KKKLSSAt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1E4071F00ADF; Fri, 22 May 2026 19:42:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478959; bh=j4ljdTpxSG5wTs+lDKxX1dHcNes13mwmx+PX0QnrTgA=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=KKKLSSAthz1qEfj3B73Ld+wNvd0+op4ftfGLjBimIkbogxRAbaovgmw8g26eXJA5d fdVfIjBLAkB+zsnVS2K8ASgFT+MyCn6p46B8yWva50jSFAQ0xR8/MSUVkcgAutqjKd jub9zl0tM/YROa4Mr1Cs4+Mp4SGmwZinXKR+lthTgksSebT19z8Bdl6Ki4fJagzFAD NJEzqfGV/MDNGlaqKKBmNhwbZLG0bDCTAvBlvBrYsp4BdUUPSetvpjW0c3/1ru1PtR CZKik399jPKzd2+Fz6puOFx0Yx+rF3JhdA+o0eI+5iuKdh5w8U5zdYP3y97tIou3lh 7GLVaEDbKgXAA== From: Jeff Layton Date: Fri, 22 May 2026 15:42:10 -0400 Subject: [PATCH v5 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-v5-5-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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=2160; i=jlayton@kernel.org; h=from:subject:message-id; bh=qKZ8zjvP2Xs35BWr9tiO7rsFDru5X9fTbNx6jHh/zrc=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGdUnSrM+7GqaXKEkmzDeA6+jmFiRrRE4P2L z0IxH95/amJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxnQAKCRAADmhBGVaC Ff60D/0U47/xb2hDeMtC3yll2CDOR5H8rXGbl3obNQk104SyLPXKgAXoT4YQRvfCDQ73RHGhod5 yU59TfIxoUc4GPcD2idBq0Vdc/pRWAyu57lTIJNpc+UiBY37dL0xhATrJgHLlmOWksLx+oZgd4F oUtVOehsjdRaE14vUnJTBiHYJZffsz6cwL5ovLs9lSui/3EaZUwP3VL4pFoDsZjUI2xdiFNs9RE ZjD9GcPpTnK64EbOvH3/UhugbpeCoDnZ+O/FBmrN6LMEWFz9Cs/ntuStJrQb/k43BmRABjMx8q1 HiOQsqHqx66qnSgbVUhkcXAHu8xoo9Txwef190facTp28xQKEmZjC0VnrMlfq6rnsXOkN4pKrZP 8k06bvtNJcIrjrvuXRVTtS4ea65lUQUZ23nf36ZY8BUZklKaEekvg4X45djNYw0vcXFt6pxKxxW 8bZWLCIlkaY7A00rnkhKzo/kERij6BG8Ou8NPZo7VxCeYdxqNY2Wg3zxNmqcawldUZ9XCKDWvlJ IXqtReLH4ZAYJoqlgU2YeRhLklvirJ99Aq0ws0lVFQgIOHVJKy/u/D6WEqak/2XObrxKxdD5IUL eLKbYcagJU9q+DmJJBhzE8LI4ggaVxtlNA+kKCdkLnZ5miMUnUd66FqcBxJ/jb5QZytOT2lSZiO 0+lzu1rj34f6ffA== 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 | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2a34ba457b74..efbc99f0a965 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1246,6 +1246,38 @@ 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 inode *inode =3D file_inode(nf->nf_file); + u32 lease_mask, set =3D 0, clear =3D 0; + struct fsnotify_mark *mark; + + /* This is only needed when adding or removing dir delegs */ + if (!S_ISDIR(inode->i_mode) || !nf->nf_mark) + return; + + /* Set up notifications for any ignored delegation events */ + lease_mask =3D inode_lease_ignore_mask(inode); + mark =3D &nf->nf_mark->nfm_mark; + + 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 +1287,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 +9715,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:31 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 4653837FF5D; Fri, 22 May 2026 19:42:42 +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=1779478966; cv=none; b=dLlEvaixA7PFzbOEQsk3Apjg3cyw8eJaj9sbTgpljDcLwHRMSvVVcVtz5FWAH1th5sq5EmyZgruHpB3o1Xjy/3jkXeTxxIIwnNu1L/QSVj+Jae3REowur52WGNcUx8qoToerePM3f7ZXSlOfV3kQ7SfSZQyAtjzLQvWgi/b/jG0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478966; c=relaxed/simple; bh=mOrxF6IVpJybRN/IbPraRod+aftKc0lxwp5617dnXbo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LaYqo8wLkbwzgkaIcX/hM3JolEdncC79jZAEgedmCmS/h7cL+Zzvk1j+VjEpAGAwDHRO5aS5TIxDPmdPrIXWOFWlXB68nC7hBU78vidBMgMkcoNMbiO2+Ejcnguk2FFx0aGjXouYa49aU7yn8DqRAn5C/EJvg9opJ5Av3KqZtIU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AkL1Xrmg; 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="AkL1Xrmg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0E5861F000E9; Fri, 22 May 2026 19:42:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478961; bh=hqNJjDWV/78Ew+yDH7eabr77QKqzz4qmqwS/+2IAGJo=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=AkL1XrmgdrBRleSlO+UsgJM8x8/yzeYu3mdSIWe9TWCFKcHSzZbj+r90zT2uK2XgC RTBL+sAKZATiQYMVx9XRsQ+HnLtwmdsnwZAgsOcVV9xADflL6NY9rKvI19ZpU9LJ/x ZtpJV3uFj3zAj8hkDmJo5CztRA3sWraWR0WGqsiozC89l0SrucDksR17iDKYnYxTtM 56v587zUcdp14FtAzx/UdjJjO65fMawAInI7faEb3D8Oe/F8MMABBN5hnbs6GEPz/Y 4gZe4EnLKx8wsSmVJQ9CCxVrmoUKmQjJK+s0zZ7SaarHCmDMtR+llVrNIzxudTI+DU 10pzyBQDF+goQ== From: Jeff Layton Date: Fri, 22 May 2026 15:42:11 -0400 Subject: [PATCH v5 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-v5-6-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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=mOrxF6IVpJybRN/IbPraRod+aftKc0lxwp5617dnXbo=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGeBpTk6DkJHHU6ENiiNiPYDVR7iMLz1nH3I 7drGIsZv7eJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxngAKCRAADmhBGVaC Fc9uEACnBCfL3ZRrztDrXQ6Ljs6fnekCHFfTWhrYQidTtonzva26TxfuneV+SHjdhow1BGUWihu HnsdssdLj1dvfiwUXNoEiPZM8zoNm9EvGZep6VI2ZPty/gXaDs0HLrNRpLlZPrZG5p/z+7bMyZa Hu4DS5/jLUqAOTVzXM57tBkMk2rqDTKPTaYsh1roz4rPpwv+abkKcS0SbBqMoeASuO6b7TZfo/M NPdZcMzoFy6GGJk80SFOYHi+WULbtou1cezyGiq1PdCyXINA+gjRR1ZTr9/CNV8BuO+w1XfJ7bQ PRPctF3VPQ6+dGSpRYM2S01GcFXuPDxI9X6Kf3w0ytr1A8itCeVgiyPrcLv2i/jLhc3X1h0vhbJ IqW+lxTZQLsokH0XVZ6pCzOp/6NcCKk2yyoomenVyim6SWcdDuMUSIzAQujEgXmFjaiBrq/8gKm iCFO+ZRCxd1yJUn3lWjI9GArxBwRovs/KT7eEKcRPfKXfmVyRFeA3zEbYfQ9Wf9A+ICm79kv5aq gPGYIHX4lIh5S0HfpTDY7B6JmWeUjoLWb1C3Awr4I0vqPiVKfJktYn/WpI+lUYBgNsk62inLDql 6BrikbmUn2RycvkEpdqwgMAraJJaKxyeFuUsYvMCMKt3ow0QwSdx+deqcJovMJ1hPW2igFp5ZNI 8q1WByOSg31CRaA== 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 efbc99f0a965..3efc53f0dde6 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 @@ -5562,7 +5563,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, @@ -5583,6 +5584,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:31 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 50F5B3803D3; Fri, 22 May 2026 19:42:44 +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=1779478967; cv=none; b=uAox20P9Lc4/NJHicigavvQ2tec7+CLeVAdYp0ABuIRJZ0+2a8sQ94gscM210V/B/yL956s3jHyMdXq3cEh0Doleq5WStXkJcbquqfDiIT8Li2ls2Y6Kj5cjUUM/Le6F0PC/mQtcCsv+9ZGj6UbCb83Kx2+zGGzPwAZ8TpgumgM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478967; c=relaxed/simple; bh=b1rU6ZAGMx709xUdqTWwkbd1Zwx96RNeV+LNlMCfsIs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oKa2hNJFul0qi+53h/KDJiKNwpSOk/qWM+IVLICfE0f4bmrKjpVTwzfsvOEY/c7aLh2xwKjbM7e9pX9KVtdhflEziE7VOWk681iq0SV50wBeG6Lc59bYdlEGJ2VnDj7qJZMiiD+guLrKeKEZVsbpsG2DZ9xecmkXkBAR8IvPz1o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gPhCAhyY; 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="gPhCAhyY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F26FE1F00A3D; Fri, 22 May 2026 19:42:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478963; bh=4LN8CBPtlSu0h1hjRMQR5ihtJ8gQEm1OuiggHng7lj4=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=gPhCAhyYDH4dmcyEn5tJrdgyPr/4VkQtzVMqhSy1EBMkhyt6Ql+F/fAnF4zBC1SQ3 BlmcU0Ko6YQ2deUhAcje+7qUekkMLa/n1NE0dsyNGhE+yZ539sf3Ga/UPAYigBR470 Wr2QnNaLTP/LSvAgIbxBsXkM9SAKsYrLZ1Jv2pq/wnJQzYnZTEpS99cBBEl5BcEM0F p6cmz8r5jmj2WvPxIJzJSvM5n4J0YNufzBDvtHZlvf62OhKTFUKq+M6mhsxa9lSni9 Jej0TL4fjveAh3FFBZQKaMC9BmXWQrFKpPpOdx/GEPfqkRjXZA0deZ8ByACy9NBn1N QQJmRaCn5nC1g== From: Jeff Layton Date: Fri, 22 May 2026 15:42:12 -0400 Subject: [PATCH v5 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-v5-7-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGeZ404nPoGDydU6cP9mtCSwKD0rYnoDQu05 DKsMbnvnH2JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxngAKCRAADmhBGVaC FTKUD/944yseFE8rQqTsizSRKDSWgPwbYMR9cZ5sEIwIm1l2ajOWUEf99Uub5Kk/TwPNBJIQktq AD2uvPOVWOHyaoe/4lIw3AotrU9D1ZHDPE1vH3DejJEg/Vj8GjqrmfI7MsB+8USfq7aRnSj10df faM/ARtMe3rgKQ1XKkNa44Pou+tb+QyIIjS6ZXc971QEw4Ddyj2te5rmMiytI0fJRXFedhGY4Do gLJuqfS/nvbr2GHGUbuGxkovkZYVh2fBBqzMRhQfpThhjE59/+obY1FksQ2QySIlJV2/fZpHn+p uHZfBNybzKrs1mp6JEi/PD+ReHKPLJP36DxI86+hmP3skH5svEsXTCkt+GNDJ7ZGfiiwKlnXIQd tax6nBQi3nunU+w0fONp6XLKHbLS2UouqAMMkgL9ap8559Hk1zj78tme9xgs0Y9FK7InkZHf5Yo miYwHPIFkVZnwiPxA4oIIEtk8zGAEDkoE7vsldDBJkcjmEfNdO2wHFl1neGdIsGUXTWeCjzyVw4 w44GO0PnR9GICXlqHtwfIeKwudKk6acfGCAUgcKvtJMu9IXuPOgyEczyvt6FFTFNaTpLupxDMHi Xv0WpZazCxldJyVVFQDabLS5wOW+pvY9j7DiRpcgAcAzO5M6zyUv55RcA13P5zgSgkEWqxT7T9M zcsM+AeKUE+vLmQ== 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:31 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 6F2FF37B02A; Fri, 22 May 2026 19:42:46 +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=1779478970; cv=none; b=aqLerL+w7HD9acVWJ98oQbDyezi5nC5pSap9FEyG4NTbW7Nf13qWn7DUyFAxSPK6wg1I3hrbey4dLvvXdsu5IvBQ5qVrzvH1LhHA9msoQ5egwvJZIWwSSUQ8Q+yoP+6KkOGol/5bO9ou/eMeb7eorPyOYxKbAFxXh+y6Csh1Dl0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478970; c=relaxed/simple; bh=qvNv3avOBk9oArnOhEgN0HSPFsi4RlLa8VUkMUtwkxo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MxLNjKz6DGRd8qOyfQ2y6aXm1YzGH7yz0OK9aMneA5/BT5rEgu/PpYIVsilhNEI0/z0PPSW4vDMPHEOsI/An7EGTfeWai2ofKLLl/fe/9xF30ipzIZXa4EewROO8o4fkwNAg5+LxVT26hAkYVDe1vP2/QyCCQJXzPuCJ7jCCnKc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lSLZ6pTd; 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="lSLZ6pTd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E24F11F0155A; Fri, 22 May 2026 19:42:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478965; bh=3Oy1/PFMRSc/PeEI6oqyJ/bni/JvWJ/Zz2Yv0mwxI/k=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=lSLZ6pTd9pbkCIjUck7N/u0rqbR2/AUjjbgroFALIE12235Xnd3G0RAXfGRxix2s5 wXp/4QUOYsLqiJFFaq9wJG+JkzbwKatEpGUq6//dBbDeHIgmET7Dw65zEyhfrQoS+H 8+xJt1To9FYHSl7cHaAQAa9+nNF5U/x+SlZ5M1Pbrfc/2nAVxek0r2EywCX8+2Gz68 SqYcXndonJFKrOlbv7UAkAl/ZLQbzCLruhhuqec5iVCBOwfVUapA5qC5O5HOXej0ne rfUknGUOvah8blm/esVFw5L82wXSvL5SxmLIOMp0OmDDLfrE4g6O3yC9t46lmo2A28 MT6NRFF8TWQeg== From: Jeff Layton Date: Fri, 22 May 2026 15:42:13 -0400 Subject: [PATCH v5 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-v5-8-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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=7785; i=jlayton@kernel.org; h=from:subject:message-id; bh=qvNv3avOBk9oArnOhEgN0HSPFsi4RlLa8VUkMUtwkxo=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGeYaTOa+mCPlZ7kyXCSbP8nY3OByaiXk9wg FH6ZaBEieuJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxngAKCRAADmhBGVaC FUQ7D/435A1kDFUXpY3BY6y7gQFnO/3NKRCec7nDZ1Pz1CG0q8wAh2/ZmQxKuyXsNIqq0NOYxB0 1gf+5V+1kBBD0C6jHDdFX2JB6b2BYsGwI6URUjSUkQ89sACKA8IZmRhuQW3uY2VENkaOmeoelhw zDubkkoFRgPRaaM+d6g0/3JcBLxQPCIMiY/fG2AxOZPNsSHW3oqlTi+WBALw2d+Q8/oKx0F34Fc zgWriBwcAdCTLkfzBzUl5QhC2xlkeTs8qfaHaSi977PmGHRBdcmHk4GVWJxQkhZqNn8Cba1DU5y YPOftZGJI+p+98aRYkRl/gHynF2b4RhgN+UNqwL6qlw/XWlpKRekECqKYdwxWJlhLnHLAcplq3i M6C6GnCgBDY1D4rHxPbd+S0aqIVdln+MJzDPwsO/a6Q1pp6yYsuFDeKp0fimdtW5eW/uTo5pUkY w1jWIboAxvMgh7XiAIOQIKZ1EXAMgyMnoYe6ajRBybniCxJW0pKtyubI/pSxshalLPMOWUP2EZN BeUYGNyP2tyQX9DCHfAjXwTgCxLfdaNLn/09ohZSSoh7REQqBFlFeOHql5DRMKV+xN3/CP0MC/b /87kBnhyp40ENhTBGuyG/vYobhevgog/SbgGVnXA67XrSiCZ6vbdED010jyVi+CGDHm08Us4Frh 1zm5qNAk1wlrhpw== 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 | 39 +++++++++++++++++++++++---------------- fs/nfsd/state.h | 2 +- 3 files changed, 25 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 3efc53f0dde6..bd0517dfe881 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); @@ -1282,7 +1284,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 @@ -3176,7 +3178,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); @@ -4958,7 +4961,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; @@ -6110,7 +6113,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 @@ -6118,7 +6121,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 @@ -6195,7 +6198,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; @@ -6301,8 +6304,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; @@ -6327,7 +6331,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); @@ -6348,7 +6352,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 @@ -6369,7 +6373,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); @@ -6526,8 +6531,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); @@ -9669,8 +9675,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; @@ -9722,7 +9729,7 @@ 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(nf->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:31 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 D263937D123; Fri, 22 May 2026 19:42:47 +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=1779478972; cv=none; b=T4o5WpKzEsU+8X0sKIpIkaoy9c3kV5VnohRT0HmlFsusU90OhZNUYVOALNXgVsMVTLrtY/ZNWCY5kj/hFQlHeGx2l2lQj7xrCsgUv4/JdCCYo4T12NavJ5zTKz6r4d3hfZk0rCznlI+UetW1f1uktshcGsp5q7v06uKRxkkcFtU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478972; c=relaxed/simple; bh=vqghVytGJM9ewOFcjl1N3PI+twoVkMVXdI4xbjpSr0Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SmETDthxFSVheiDOaMlT4C/KCfYqq42ie5lyVLV1tnRQ0l32Wwd9wYn/w6ho4sckzSt7o8eIRsPp7Zaeca4QzU51231LWmdW6L9CpA7eCKT4yPJexiYxVnHuQdzbB91l6wDGIrIPljzBPyOWBHLaZuJjRBJIHQluYFlHggP5v5U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ERW93OgN; 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="ERW93OgN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D1F221F00A3E; Fri, 22 May 2026 19:42:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478967; bh=S8/eHggYVU+2t9PCEeC3vCUEOnADRDeMPFsgNA/zLmM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=ERW93OgNNzOvLST6huZ2r+Gww3lVbw0Q4AtxvsngIvlGm7HY/tCWY/1LYkdPpDQCu 2/+bDWoOvgH7iSPhh90aI6FTgV95j9cXyhBu5zEWEyCal64Y+SHhwizrbJgH3GL32O KeLmXGVVPXkz2yOXnrhlpHcCgPtw9Q2tCqpFnCOJQq6MP0SZwRocgYDZkK6HNgYgqn dwv7wOkBJj8Rc4ccLgEk6Te3il4+s8IGOXpsAMUHROaVUzqfSs0Bb1AiduOfT4Axeo N7v7GFhJYvO4ynbJRlMpy7Uv6auQlEE1kcJw/qI09vNcWkKmcWw4s1q3infZDlH5bu BtqMCsl7sAAoQ== From: Jeff Layton Date: Fri, 22 May 2026 15:42:14 -0400 Subject: [PATCH v5 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-v5-9-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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=9084; i=jlayton@kernel.org; h=from:subject:message-id; bh=vqghVytGJM9ewOFcjl1N3PI+twoVkMVXdI4xbjpSr0Y=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGf1T2kcGpxcLm/YjzBm1TAWu3t6ZvCWnpSA dGhmimPu3uJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxnwAKCRAADmhBGVaC FUqTD/4jcJbSozm0gNwUFjo8/QcB+WExlGG2+PFFNm8uppF+nRAmVj8MMkaEs4PoPhU3uaRcHuE aFn4+ss1XZ6WcynRw8JY/rPupVi8TAAabgmY9GCpMjDIgRwF/O6s21f8MmX/1vaklNdS1lzmGe5 ok0P03i6TQeTECJAtev6ZltdpzVpHfb0ip3B3a/JkL5V+C2F9qj1b58F/smze3F0Ou6gwxn5KOV TpuG+Ogb8dDYtNC5UA3LBXsi29h3bvdLmP3FW0kCCF720PX3zAB2ll63ovueK+qZzoEIv4Qd+C8 zBOl+VZEk2pvSrgxQh0kcCvMrkMMEmengSLK7y+lrJULLh36HoPHazG5vUeMNbTAEtUTrDrWG5U LNYntjJBkFp6AlZENytijloZt9qTSFs6X8HhWGwbi3R21TCFFGk7wSbh8x9mo41lFcaWHaZ94WC s6Bx4u1v5VkZZx+nZjrhoswGg9b9Sg+PWe4OoKBad3J2+T8rT1VPXgYQ/hGwUzrifVxQm/FBmVM jJ/ZSplN65PHPaMjuWEqi/hwUWOv25vr6oc3/fDNJd5PIekdNetZeRuVdWaHh4rtnGmzSxRAG7+ TY7ibG0e4jspkd8ciY/mcxLT6Lboe1CJzoKHISMFqWxpq/2U/iUgAW4h0ghaUDSZGyoTv+xXVIU IgYrXhdk53TvABw== 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 | 121 ++++++++++++++++++++++++++++++++++++++++++++++--= ---- fs/nfsd/state.h | 46 +++++++++++++++++++- 2 files changed, 151 insertions(+), 16 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index bd0517dfe881..b0652c755b3b 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,79 @@ 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); + for (i =3D 0; i < NOTIFY4_PAGE_ARRAY_SIZE; i++) { + if (!ncn->ncn_pages[i]) + break; + put_page(ncn->ncn_pages[i]); + } + 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) { + nfs4_put_stid(&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) { @@ -3398,6 +3461,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, @@ -3410,6 +3497,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 @@ -9692,7 +9785,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:31 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 1385237DAC8; Fri, 22 May 2026 19:42:50 +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=1779478976; cv=none; b=Chb/7cDj7ZfRhwhF5echvybZgI9dUQT//luUOKDeiwYmsRsD11W+TTcPxfgCyLrASW/JOVhAW6ndKu7gXWpY3yzSQXEtRRWQdeK6ZBIG0b26ej8+No2q/O1LTupgC4x6DV7P+Dn8K73jltBV7pky6aI1pwjbenFxoAG+aS5foD8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478976; c=relaxed/simple; bh=FtnCORxy2BfjqO9MZDWFh3XwgucPDfYdWhJHCODQE1w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NdGZs70di1ELSUcE04mtpDiAv/yjKfsUrJ3mQcG4uPYj9Duj8OrP5roItMigG87VWlG5dyxavCJJIo9K23771AFApJdHDcBIAOFQHkpU2D1NsKgC1DzlNRxwb3tPeMrdWFSxeBhUODQpEgRwFvOaRF4orjv2bhCXI9sLjEchRvU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IubbekO7; 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="IubbekO7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C27C61F000E9; Fri, 22 May 2026 19:42:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478969; bh=Yj6UOqqvwVWDInW+0SFu2D/4sDqYI+tRIZ72Hg3gBMM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=IubbekO7Lt2V2wfDqWYzh8RQtU6nJna24meIUdhbpwfwcFq9H5lll0k03v1GxeelS rD259mBCM/Q2gb+8o5/UZkpxncPzMNlZNE9cR8AZcoqO8L9xE1BnbIgq2um9h/Lp66 MFo5pcnuGrSoRw42cnnrM6xtmGZNIjHU+nSUfySeTbAi7K8+PSoM677+AdGVEC/ToP 80kPjYrx+/F+273VC3alzoo2fVJw1NfgRztamvMg1r/E+89ZFwy+ARIz+BJ0YA30AR Sf4GPhohE4s2MAz7jLdFm8tPCRseedaxKMgfPbG7qanYh499823JUfaPQo/5OpoEqC 2yGavzpIFFveQ== From: Jeff Layton Date: Fri, 22 May 2026 15:42:15 -0400 Subject: [PATCH v5 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-v5-10-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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=23199; i=jlayton@kernel.org; h=from:subject:message-id; bh=FtnCORxy2BfjqO9MZDWFh3XwgucPDfYdWhJHCODQE1w=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGfdILMGODiE/cDRZM0ZHiZ6ESuTAo7jv/XQ 8n5Hl79fO+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxnwAKCRAADmhBGVaC FSI8EAC81ZhPJe63CpLgOoVN9JzmU09fGydCIsW840bmk8umh3BklTKzmwTxBA/Iy57INXLgmtQ TQwdKkEEb72QtD98vbJOh6I3Wr2X8v0+6+zJuxq9Uii9s4Tz30FHO8/CfrF9TikbqwOR30SD0bQ pdvlii+6FDfILnEUd5K/YXq95QpEOA9yPjYU1x2VC6Fg1ZlbaQzsPdu7mL6uw6OUCHuZ2lEqsMw ZXu01+u90uBcmHs8XYCmQtgPrnK4x0ZZFoaMHIItYWeU17TBPHuWk8IkU+1mJlalv7nbSt8YvS/ eKm3au8wYDgTXSq5M4mM+e/eqPr67mvqh1TKrSXZfYbNuFciF2VB9p9+Oolw345kAxMRlC+wbFt ER6Vp4ZQuTOWPo/SoYbOLHcQD81zsCE9CkIsOB2tC7z/LXB37/6O+rl8yaDSIs7Eqn6CFhsAAYC EUnzq/rkkSTPZ6fchhf41ZqRmcIjuiYq5/6Iy1mRnXPo4BxpC6LCobkgV0d4hrn26Ht2S7xPTzy FvxGu+If4WJ57i96RNkBOvNosd4fqNGm9GEhU9CgJZCgzlKUHoM4wg/NrL7ZntsNS+5MObHSFRc DADS7OjKu7x7yLLnCg/oyv6FUYL7MARxbi9g3rC9LtzBI7u3tfO8NrtNz1O0YcyQ7r6AkKYcGXs ttRZMybPDYsyp3A== 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 b0652c755b3b..20477144475b 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 @@ -3461,19 +3462,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) { @@ -3482,6 +3595,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 @@ -3498,6 +3614,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, @@ -5730,27 +5847,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) @@ -9858,3 +9954,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_NOFS); + 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:31 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 8F861383C65; Fri, 22 May 2026 19:42:51 +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=1779478975; cv=none; b=X+YJQ0qFnglyBdLPBt0sY2/rx1RBABPz6Vtsrhrq7LT7qqP7u1+5byjEovJq3eha3Nic+DPlqFIgRAc14xTZgvF4x1xu4b8faChAK/XaI9CwrI8MDY/zmXVcSUTcx/Va64XM6nqVed+NO3oC8Z/LS/9wFjUdR1JwB0bZaM33LWM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478975; c=relaxed/simple; bh=iyMvf6KwHA7kA23c38ActRC5y2b23U/qezVxBFDbRRw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mBZOzCweTk74mejkzmsKQLsvHYXWLoTjr86RPxxps1yQ76Yi3LOMNCfhz7efE7EOrHAfxgDRX/zlubljiFqz5vgk6bShMiqy8MCsXL82yWT0XK1d7cDkO0eYWE0AeyYC8IAroXHNYUQhqwyEmULVrg6SyC/FM2cT45nsWBuwT6Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Z7cHu2gY; 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="Z7cHu2gY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B3A041F00A3D; Fri, 22 May 2026 19:42:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478971; bh=+7uI3caDzWXGejXCsGzeDAn7nb4kbN6aZKDVE5PQHIE=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=Z7cHu2gYumy6C8vjSoA4YZgNyyNH8AN0x3qwqbECRQAJJjNe7kbcR8NDv50mAZSsi 6IzkLPkn/k9ojhxNTtpL927aBVEna1vof5mhhtwYAR4fzd+tZMwDNftM8cebPBjvS0 UuP6lCbWiTXcptjBmSuxnwsVI41euo0oLXGl/ZaUTYHMCTyq0Xrl0NdajqR+8D8Xi9 RbcY2bk/TRAE1PCZ7BV5cW6gYpFgQFIjAXxDfojL5neac1x+MxGpMdPn85y6jF7IUw EwuGcJtOWcYqF3W1V7UaA6pOlO74+DZLO/f26lez/x8wDKosRgdkYDBr7MshwPZInM +oIWqfMtivIuw== From: Jeff Layton Date: Fri, 22 May 2026 15:42:16 -0400 Subject: [PATCH v5 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-v5-11-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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=2040; i=jlayton@kernel.org; h=from:subject:message-id; bh=iyMvf6KwHA7kA23c38ActRC5y2b23U/qezVxBFDbRRw=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGg86+XPSB09vhwAaobm3TzqIcBD649E+K+h sRfqgHU6wOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxoAAKCRAADmhBGVaC FZ7TD/9+VuQQRZGCo1qWn7L1gwIGkx96s9EdaI7j8BAmEniThrIEIwl0U22KcQ34Shzk3V3evr4 moV2XcBgz5GVwq3sILWIMoIqzo+kHwCYzzQ2BpnP+lblIkSEJL6W3anybqYPkK2ByHhVQd07wZM JblLCFx6io6KROqDmkdNPPKou7R3b4aZTHWk++ZftiT/+j2ETa4VCUCfLKvD5BEUDz0kubRxk1k vAMIpiVLp6ExorpQj0WMYNprxKbr/X/2zCzOyn1qs0j6gAhzWvHOkWnCWNcB1LdivURpayiHCZl d5/MzmI89h/nlbp0Ed2Mya3Q8yNiEQ5Ete5OERx2wzwxlTl+Zg1GKXNzqSxYDbgcPRAP/LtnVE3 HvL0a5wxrndkxy3Q5GiIC2H/hPxioyzm6QFlNcdbS5659WhQvS5tb5zv/SZzrk6I+Suw/zEWlen pZM4EEIWvxCGRolKXzyLragVLqPQnyahowXYBAXLkviWIBGSGj+hIdcXCrJ7yTHhZwLsohg+OTW ziGo8/dqO3HA7+26fjpR7lhebvBzreQES8EzEdU07vNEMOXwUKlVc84dm11020o4s7WcawnDpVz cFBTuqFj4Mi/M2G/SggQJ8rW9IwUzocnPWhJEjHEvotAhjc9892Jb2qZ/UxdyEKHQZhlO7/CRPB 6JClzUq5EYQFwow== 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 | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 20477144475b..e00b4463c89d 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -10035,6 +10035,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..3d0f0bd30d90 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,28 @@ 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 : NULL, + name ? name->len : 0) + ), + TP_fast_assign( + __entry->mask =3D mask; + __entry->s_dev =3D dir ? dir->i_sb->s_dev : 0; + __entry->i_ino =3D dir ? dir->i_ino : 0; + __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:31 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 04E7637DE9E; Fri, 22 May 2026 19:42:53 +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=1779478978; cv=none; b=f0uyQNcBs6VzgSud1Mf3zMplzA0fzjyYFxtFzOcPrNFIGryw9/yutqKJT8vswLJFUPBOeV94VtTaw4uBk0lqw8y6Bz0q+9fp72A9sw6OM4ERZf4zSkhkotDXj/w6MqnmVjLBIcTzZ3FMKSSQaCYpy5q8MxWRgedaNOfzfZm1d2c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478978; c=relaxed/simple; bh=WtCsTt7GqWI6wIG7UjJHamJhQxbCqTdMWHwIGmCs/cc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aTO1kEqih2On3XMqRJNQ9qeOOadxrC5RAtpca9K+O+dwgDAK5GuYFmCYjRG8fRMfVM5F0vHfhL+t8v/hVaGeH60OBonGiVyWuTyoHvPjNLXA8L3pAhbeaiUWAtnGx72Uf4vWkLqEcJwA31ufMqzFVgpTLtFzAL9bBYTyNAb5QCo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F2OD3lls; 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="F2OD3lls" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A38211F00ADE; Fri, 22 May 2026 19:42:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478973; bh=pO+8xSv0vMbVLlIOVu1sUSgwIlOn2Ujffy4e7uLZjPY=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=F2OD3llsM+BfPC5qK7lnR9q1wkDsqN1v9QYtKD7koZmY14Wnac7UnmlcQqVZEn3T9 D7LMDkKthoOgNHWNMCNV5I4XRQFHfK4cWXP1LDsjKmcxMl395b+GqY3StRBfV6i5+P Pde5VZSghSm4nPmnEZ2w9qeM//P5Q84ywJEulcQsCRbCSjt/pPaFZPjABOWg1/mro0 HVXXyg/yA+RO4o4C1QXSmajSzmAcZc5xUGz21570YLyT0b4yjGrWADe9Gh9nXqfEe6 8u/H+fBF7dzT5GXaNOY5B2cmNk2eKytQOL/lyk4FTlqhGiuTLx8+kSCC2IFKjr/wQ8 Bqamr6U7SWEhw== From: Jeff Layton Date: Fri, 22 May 2026 15:42:17 -0400 Subject: [PATCH v5 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-v5-12-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGg1F9tddsm0RtgjBxOa/CNGAXc7dyF2CeQW A0ASdjs3tOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxoAAKCRAADmhBGVaC FdN1D/0RtcRsFtifUyIkdME38Wpl8Hb/38wBnJ7oEnCfjEQHWqws6gK3azMiIyvo7VuZqcd4Nkm ohoF9U5w6I8wbP6sIZO83XD9J3xTLIqOR1NrlUm+1cVfQDLwQZSkYnG5VYha4zcR0GOK9HBxgoX f7qQ+I5+5abGN4J5qW4+gVtdUKVXZyouWIEVrAwV6INDKthodrgXZDrmHwNObV6OWWvk6mlvRSl FH78PfZ9oRfER5zlFebvs5EpWDE0qZ8bCjIUNWlrk6Fsiw7L8wenvX/Qq1SnmAPVzQvB2Y6E7RW cKRk+FWNnDJVsK1rYhx3m4PVUqGy4gWaAVQuPXF8acVC548fdn6cFSsws36wy0ovnGOG+nD4ykx hUkLya2EaPlsg81izFrwiHHck7AgBya4KAqT/nznhsbSGVF9aBgJErMnpIjSwgVjZXL7zW5lxnL HMxp/UMIAEQEzcoNJPfY4wxp8SsgrCM055NOasx/UCwV9zf0cchFPR8gGpSQ4Z0NiTfdSsw1ZhP 62DuFww8hC3hz5dEXYRYfF4baXjHjEW9a3Su21CgNi/lKdHlI1eHBaCmSQuv3DyaJSJjLeDs8jV 6R7B3ldvq4NeGHOTMmM85tVLmmk8I8MBmZJ3CTXMyNsrqRJqL+tn+Sv1J7VdD2M8/r1k1LRNHvH UUZtrRGtu8kL54g== 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:31 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 B627F383990; Fri, 22 May 2026 19:42:56 +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=1779478979; cv=none; b=Harsws2LWiNc6YgwnJSUGXx5NF5X+Nbj/UBAXPhMfZ0kVBvcoZ8eBqpb/b2VdI0ZqtgWZjxvThr+pwpoYwIby+tmUuxGVNuO5vM7Zwmo1wpGu8a1fJBF95ZiyQjaQul7gmJ1D+eutnCqL5yKIkLqUEXMH/E/2kVa8ZHsqUGSX3Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478979; c=relaxed/simple; bh=AnXDCmJFZYm5CvJ/Tqx4ECFvxiyWh0qg/VdF8Hlk1hE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qMcjQ+dgX6+06fqbgE+/eAjJYLRjk7ARVy8SSaBN1Fh3l/49VaOAQpdEpc2zyr6J3n7NhLbJO49k5lYSi02mwSWQ9+zy1EMTEvmyxeQhHiCl3dCGh16DanB9H/wpi/LJE1YTTTzFRRVyvM0doCnRNawcRna3yfjeUOJrrK1rStc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AO25PpFD; 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="AO25PpFD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 934361F0155A; Fri, 22 May 2026 19:42:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478975; bh=DF5gZGDIA/XCxzRoqwszAdw1M2a+k5vgSFZ3a7XrlYQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=AO25PpFDfMjgr2PtMghhwoGlLsOdtxSUFKeCqKL/xO2bZFdSahrJuxpqgBF0Aqi+2 ymQ1SnQpGbmaFrQlD7fcC3fsEndRYX+Xg926JeinYUKYlLOB74eWqMuoYXpHBhVmSM wpvmSVf7TEgaWXF2KUwK9BjA3r+1LY6aCp2lFnD1k57dAt9DRxETkkIV91VNZKo+7u 67f6okgL8IKDqZ49mRcpjIPsa1qLeYezbWxTvAIwoZEMRhbJZtMFEk7H1x81cadk8b Ls24gr+VItOktb9bD2gFXDKN8/1ERbBAcmxw8w/2ep2JwJlZwcBxcvhxE1+mh1YFV+ c0Fsa4a0g+v5A== From: Jeff Layton Date: Fri, 22 May 2026 15:42:18 -0400 Subject: [PATCH v5 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-v5-13-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGgu55ERAimtpOx+ttb2xhMhUq8zSijRrGXA TyB4g6HzD2JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxoAAKCRAADmhBGVaC FZ4ZEACO06o9tQdf6FH6vPdt2/MxjmQvQtmfUkE7r18ez9MUREh4Wd3lQKTRwM4ABw/yTU2WKyP GnmY/djaAAA7pDbialgY1YS1gK3lMjWi/0iaaNVaFVRP6IKi2TG0Jba68GSCZ4y/DsxpxAWicT0 e0ZxZyxqRyl8bsLCeARS7WLhsMrwG2bTviGAIz68knjmfbXA1jD7UFTYuDJj8oJeex9yHZOzmiK N3eKVaI/IhhQcuuT0BPV8uTORzmlaA4oekXAs3mZZjojx5aRvou/7r1xQxQKrysC/Kk61i3rb+8 UL8I1pZEuvfxmsrXLx6nU+faVtmgPUu1PPNP+2Go2UkR7cAusZpN6J0+tPFkVh8Bb/BJe7upW5Z Dk5GafOScLKxx06QpAea1kbATifPNwVRgb01BDbvstao/fXjmZH613laS3itO5fZZCNRT83qtOM GVshNAOyqITfYhRl6HEGj/fN5XsVci+pkV8u5Mhhxna1o0RwsLO2CNVHlJ5hBiTgj4UbqcY2Qx3 +bszB0wGXJLUYdpzcFJGMz02RbOXaSC0ECvdqqIP96DExuRefXyGCIwungPExHfrkdQgg34pHAE Ef43wZp3z0s1L2aLP0sAup4rDwQZGdU+Bng1cxXfnHx+0nY1JfwGmSwgo9xnY/CTSzP09Ej3C6i 1FO0BJkKfeNZpuA== 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:31 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 93698384CEF; Fri, 22 May 2026 19:42:57 +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=1779478981; cv=none; b=ZsqTEQU4K73d++/zBZnixNiALL9q5afhRH3bw8nrwfzrMjqxEOJfRpDpu+HSJ0iZwF/yuUOWnCzeHRRNzEI/HdfW6eyVk5hu1sePzS3VQi9KB+UVItn/PolZt2Max//Ln3NStWv1ohaFkaeix/oIDBGVahswHOLtbekWwlx3+zg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478981; c=relaxed/simple; bh=/nJ1xNNDJ9rJbf9EQXkdUUjwKKr61STzhNKZjVXGJbQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ETLAseYGGRQyDQRo2zHSc4Xa79szk6/wI3pBT5aWlbbZqphrnIuzGL0qyfS1LMi6fzRmqE3iM9KIM2iYZ1azHiim/xLCD7l95Fo2w2or5TyTrsLg9Z67DYEe9DtoQAYQKzp0ZocBKcJOKqtVNB0R1ZKysNdR+Q2DILhmfFKKYD0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WLn2RcYQ; 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="WLn2RcYQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 83FE61F00A3D; Fri, 22 May 2026 19:42:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478977; bh=0psYgh/U78Yx/gV/O/+YpCNlLQ0kiZOK/pcEbcuUCHM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=WLn2RcYQ6elAS0QO4hkYfS9zg4eucCdfmOBLOSLgA9+MZNjvEnkjrBrjaLje4wngH l9rAZnvvZxL+Knx1xwIOd6jvYzg5IsKANpZTP87+wjvowvdOLRCYJdJhDRASoX/J9t PaJz+cNRnZhCMQ6zEWAc+ehmqnVdCTy0FwBdqrCqdVqeLyQIeBV6/RpbHxdL8imxjQ c3lBMy1OszmXL50+boqAjMGH4ocKWGJCD/oCtBW0nStW1ADwWgCM1ArNOCj+/mT0fu 2ynx8dw6339L0T6FaNJRAsxxbbk/84Riwsmc/QTArspQ7vJvqggaIBkUxZkMz1owMV /jhJlhgUFMnpg== From: Jeff Layton Date: Fri, 22 May 2026 15:42:19 -0400 Subject: [PATCH v5 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-v5-14-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGhVRmVV1RdAbO5AF90jTEqpqzLmS5q5Ef6d YFBjQYzw7uJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxoQAKCRAADmhBGVaC FYt1D/4gDF21xjGVeK2OCgNDJDwwQIAhQ+POJRW/LnUCyBsCodppfZgvOlztiRxTQY8hDln7pkA /0JBBL5d3Wm5z17lRzJer29pJX2RnxyHJNE4EW8GUhCCfgsEMpQ+8K24h+BP2GS45JqjLXuuCAQ AOxXkSg3co40fpNg5HoRTvTNMCBGZu0uO+uFPz+jEXouihz0LAAcFOt4XHYvy20xnAaxDIMvpSr X9QCRhnBITWU4+YuI7lIAymK2kYu0yOiJMrRr2k4iy7lUx0AhS7ox+64wJgEAVE5xyAnhRsRplR FEcV9sNWyh3PNNXA3gROeqkOkIyofFHUeGftyvxg4CRGcT+XQgfHnOuCvfAUxeZJ73BSLte9iy1 SjeceyT18Sx089vx2L8GaDJxBsxSRnORbFkW6rC8CyQxUFKLEgUpp7R6MAjEzCDdqn0VoDy+ThW TerSDdP2CfmfKB09+/h3NS2HfOeqo5p4VzGkexzQMYn9TRzmZ1fIRP/Rq7P4+aNMiquVk8Ak0xj yA5DeWdIMtY2YJcLfa0PuBDkHDHkvT2Fp3uC+L7tWrUo1kEynA+M9I44sSfN3fWUQhXNd8/yLea AA1i8e592Ht9S+THZ1rNKVuNsiulM00HkfKIiyULDKqIeWJaZpI7IHPCK263be5r8YkjCyyJP90 d4H9BqMYUkzuMgg== 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:31 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 757BF385D84; Fri, 22 May 2026 19:42:59 +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=1779478985; cv=none; b=m98aZ43G0kyywGR/t6fmfDC+x0XoUCwI5wrjGSf4kmgeWG9dlXBGa8fzCDnhfNP28nssqYUZjoCZYskhRFaqNdAIHgf+3Lg4iK15XFjFMN67BkGi3FnnfLMqwryFmyHqVhNZhfWvHmxL88kx2u8It741gytHIZqYRu1r9aD36m4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478985; 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=iITJfO8tkb5JZ/l+W3fLUOOuQBgjdDkUi2zXBEgJa38/8smnE0V6zwRw1IJO4iOfR7Vlq7uPx5I8hV6SXE8wzlzymZzI2IG+KnKtgSbfLCg7lJc/RmhsUXeE1oChHWR8anUHzXQemHR3A4NqvvButvutx6onVTHcbi0c3djkBA8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QveQukr6; 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="QveQukr6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 734521F00A3F; Fri, 22 May 2026 19:42:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478979; bh=MK6ljeFsXZ3jOZigE4+tZvoHGJwTrFzkGpt7U+sHsGM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=QveQukr6082kVrlNgl9kJKz//MxUWwGV5SlhrTCRP7A/Wb3tnorS4lscSFyBYx0MX urw7ZOWfhQo0RD84YEtVLcB7xUw6YDpZVTG+MiLjuS99YPMultuIimKvqizKguUIAO 1vewX/qA8CkxKP0Z0Ef4xbFEVOWSPAyINBlzvPsm8Y3/Jb1fFgx5YW/2Nz6psuPM95 L9dkX8a1PwwbSS+xR8jYLZex6RYvVqR/+U2qEolv8PX8XptgXjJ8fUaIUHv/7PTVsf wa8dUl5IEP5UZz23cL9Ul6r6cgjdEVUw7PCvZuAV6s7m0/0yaZr0ev8ZZSt6gTZB1D kIZf0Ji7zN6cA== From: Jeff Layton Date: Fri, 22 May 2026 15:42:20 -0400 Subject: [PATCH v5 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-v5-15-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGhd7m8pA5apBNOYZq8RdPE8niFKXspMO0sO 9ive802MQmJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxoQAKCRAADmhBGVaC FQoGEACbe4pqKKHeYRjhNWVqNClI0adVAm9B5FhedGGdfepFOG8qoiwDwcRBpdjZ0n5U3BmqRSC fFDNsSn6HDQ6I2FyhtPw6XWdUO9dR2XcZF0NDU8UgZF5FjMVjXaMj5FWvZaIDyfoIapfzY7ypwb iSZLQrKKwnv80EktPZkHLmWTjW3yCTJvi9/NVNcr0EdUaYcIIxMsNxm6jbxAU8JJPGBD37RFtiB hco4Na4TWfHvwcgvJR6VjEiIagtvPtCa/LUIbT2+qJXTDEGFWDUhfnuBgxoM786NN2LFUkSvTwz kvuD3fEV7FDvZovB5+NRqnbgozgMHh/l19anhHXYJYMDhLOQLIfI2jHLryr+dBgow9dMpSUzI+p iI+hi/5LJurOxzuX2+HPcP8OmdDWyTvfNg7b8AsPC1Z47FA8rh+Kd5iIWgxAP/ysXxkZ8vHEL/u gsnbgsSyCT4qFrWZgxM0OMqwY1eqxaKzNKE4A0AfpSkkJXKNkbAUD+veUQZbH4vn047jEwmODXc diegWqpc1guLpP6krVmatj1TfdIVVFDjI8tGHORiujPwdMNNHSwTNGJ5An1Ch2YOYHtfEpyznqM f9S6OH2T5AayLxE5jiLgknjDO3W4yxWraZeuZ1FWmZWDpsVi3sR6Ix0DcyfHCqHC7Js0bVL+6sE tmOlpMLoFgDVYdQ== 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:31 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 D06F437EFE4; Fri, 22 May 2026 19:43:02 +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=1779478987; cv=none; b=tA2mlY1JWYffmBSrw62ncijRSEbyVcxmY2nZp0Jd/ZDtAIkNGoEu/v+T3l3i34izg1FAMCVvrbH9seweftN2ITEeN7RNsdWYvbRWSMpBVZ2BBMZerUGO0BkaajI/qprrkRRRcqMXg9thOqZZeczFq4f3Q44x43+POotO7hjHPUM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478987; 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=urM4xKqE3lHPeNodzQ46vhNqyuVmdK3nwT4zq/PVs1ebguaGd9L5HlBkqIGm9TxgCXnk6ujG8EeJR529WIQpLqwYBYTsGf7Jt2k3pvU74SqWJtfGHgFLOISUhLKXYQzBvnk1IBvJFxd4/1p/YsDgJJ/ZtUQIKyKKR9V4ihbce4w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IqM8bLJ6; 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="IqM8bLJ6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 630901F00A3E; Fri, 22 May 2026 19:42:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478981; bh=P7GJcWlAnn9onaeiQvrINQHRw0BOo7qTCfQLKMtXhO0=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=IqM8bLJ6GaoVNaFf6EF0q7rrJpqm5+GOCXESxA0nSgbESHWwSce4ffynpzR/EBgAR DG9O62FqqEpjxQKVU49UIfx9rzyVfRTDVjkGuF2M2WR5iD9VOpXt+jGFV6kjyUQOjX TPIP5f8ZmpRXcX6oy0lOpBRWoHxMfXi97wJLWudSbBi1hgFmf4spKdU8saf4NXilK3 5sg0b2Ryg5v/9AbHLqsMqCPGLWucfiqz5YbezRN6zfewHAyS8a1vfSE0DQJ7q1edc2 +odZFZxIp9kYx+d/Uwc4WpWbrUEariRdrWTqtNUPnkt+elfKiKw1h1ZRWoKlAeEy3M 8QvKFIp4n7wZw== From: Jeff Layton Date: Fri, 22 May 2026 15:42:21 -0400 Subject: [PATCH v5 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-v5-16-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGh0PJVPRr+WErxp1Yvr/esjfC155ws3p2Q9 FJxxhxBlR+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxoQAKCRAADmhBGVaC FQ05EAC5a52Inkaw3RbneoQbdgxnYUvWSXENEwkCzh/GB7zq+0ssPNnH7SGsPsnhK84uAk/K9LM HskSZ+tp9lHoYHGNP4LSvfp6/TlubUVO43jIsQNFrID65mLch3UzueQJywRHzCdolClAWzW+YBT Ui6EFtpKX2XzXYyd6VFJ4WEQ1NVUpoed3BToWuXNW6UwBZpqoIxdbFBIWpikEFOsKJl3Wuo/mxp oKMShbRBrpW2d+FjCTipbdfhUu920QcdIGM/1drRJj50v2NOlK6WYiU+h+UMimVhicOfla1rKwo jh0UpBxhows6l2OD1zgv9zman+VozpTFnnMbS2dLbJpr6UTAwls0aUqTA8G24KRKgjd/0wx/GJz pGAV22t/MZTZO0h6zOnLlV7aZFPRq9/KZ1nJuyWGIJ+f23jQJvP19PM24NaADdKwyjOfcZYJsA9 Xm3dsHZ88PsSlwqNLktk9ir3kgWzZbBWKWF9+x4za+SLsPIKWlLPPoYusDzlEPamltmp0pksv0t dKXdfE35WW0a+N747ZPEhlfmkBZNWpId25B3PAp1sVBnF5otNaa+iUpUsgJHGtUM5xdUR+qCcXQ zbDjJaY/8t+udxCC5n6Whs4frJqgfPVuJMMF+6mn6QDOMYhw55zPCLlMw5SWGfOZDrQLaD5FHYh 3vnM3LGhjsPCTCA== 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:31 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 6146C38737A; Fri, 22 May 2026 19:43:05 +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=1779478990; cv=none; b=lFO0/ihtEfPI8RgVbpjB4iyNjcPE9X8p4rzKUHKh0lbk9fgNen2DuZCku/Q4HE9jSYGh898FbVtBTF2d/L0JEK1pNc7ikpAEqhQlsvay+VpJufvfQYfUl6ipKHgGmx6BDyjoQ/tq9pmPIF7+Pe5QHMZKQqT+h9ZVNZtfKnR96RI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478990; c=relaxed/simple; bh=KtpHxWDfDdHjB8yg9KaoXFiwQCWhWzizamvNaqnAIjw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NqxzzFPLU8DS0w4eW3rzDnxRHQNGwstRw2RwcaSqb2xdF+ykoG8w1FEp9c/oOFb8K+s5yT76skGEWAPXAZWOXOXNK34FymFdPeptbBI98ldwiN154S1l6QyVUccYFt5rma/LMVwG1CemWbP6UwypMWLqvIRDZYXjnkUNGiZNzis= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MSJ2viWm; 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="MSJ2viWm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 53ABA1F00ADF; Fri, 22 May 2026 19:43:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478983; bh=GXO6t0Kw2P03u5JqorR0nwll/zm6VVQnFtRlVoi4ApY=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=MSJ2viWmkCY8qiuDTC6zJ3WUMQl00zxO6AmXyck7f5/h3+ktXEmo10Hw+p4PPoMKF KcpgU8D1GmzXfBOieKuHgzeceHVus0hCy7KwLoSvHtLy1jOF0WVbQUUueQMKlyRYG+ 6u/zfsJdGSrJ/t7LC2/TuhejcBBWwzgUn+oV6woXG2UUFjdqpThuerJAIn/oHzsLeg 4JGKpup6/RxvSbU3N0B5rtMgrgJCFSe2rjj4kU6R4Z6ZkgSyDfhhKfACC3nxaJoWmT rGdsqnVi2hiPH2+JMSg8ujCQWf8gNNS50BJvttIfaUTFmBWrNY/A2bmDZ0RXl4cMM+ p22N3lGMm+MYw== From: Jeff Layton Date: Fri, 22 May 2026 15:42:22 -0400 Subject: [PATCH v5 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-v5-17-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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=KtpHxWDfDdHjB8yg9KaoXFiwQCWhWzizamvNaqnAIjw=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGiTX7+aehkfOlex+4fvb/Og5XfaEs2qRN6E eamJk3CKrSJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxogAKCRAADmhBGVaC FTZJD/0VhXEe6Hv5QHGaTWD6YUWs5UqMdlErsC7zVbRR+tUwc1VstYei0ZMuhujiCNIpPNqAJH4 jz0ZKDwAwgQPL7pcwsh3KxPpmkZxDO2M7Ovp8DJp9o5XRu0Ugr1r5nsXY2hb5QwOKTv2PcIUQfa 3+v8Eg7ZVznmQ40COcdBlEREgJlBAEKir2WwIqSANGwYOD4W2FFkQE9E3Av7r/iBfzK908efgw3 owf7KTpu9bswIx0VrU/y/sHLEVBFe+0QI/MjL1lIhA3c6zLnQAvXdNAM7+LfD69vFpQQvO3dY4e gMS4a8rnDHwTcjXYQHldCOLObSRVCQyYT6dIV6RsuYjKuxfHdZgjoyGuTX0cl/HZ61XMb0oU3fI UgZ5xtqFtKbYubas6Czy8izu986wKCaoNCxopsklyp3/26TtW5S5IuOjMFYD5UPrvZ775Kim16F t69zIWDc+Ra7CrAO4JIPSaHtq01MiC8e01EZmc4miuCKb0/688Xx3689257HyGavwHWfjxHJPQs 3nHeQ0y7wI/v3ZplYonMB6r7OWALm4/MCKnCe3Mc1qXY3v9nWq/lU6En66kflhd1QTkwnHfUWAg IuBIaUqbSmfq+oNH4VOcFPdRPtheMMAdrzgELa8pYqnmYF/CoZ1pf79RyLr2r7TE7ZosauqN2Ov WmJfM0g2OmNLmCw== 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 e00b4463c89d..eed997d1c88f 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5179,6 +5179,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:31 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 CC26C383C9E; Fri, 22 May 2026 19:43:05 +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=1779478991; cv=none; b=SlIQ8Enlt9EYN0y9oMoXU7WWCeNiChdm2GGHkLktES/TQVrm70eV/tM2jizXifSWXk6n25eEstpyuWpxImoyfE/OzdPk9DcsekKed6dlNYblt+AZGAuA5amZH+XYjWMcLKBobAGg9P5ze94rtKB0V3xNH0YtR7N5wrf8NE3LIOw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478991; c=relaxed/simple; bh=Y50oSV6B/JehwRBE6ozp3wxwE6QnIRaFrxKuDBSJhao=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jRlaMW3YVBvjsNSQRyuaXCrvYxo46N5TcRxJMrNjWxZ6Uu0vL9fxcPI954wUMsxDj7QVGji8m4CNUhxtFfqXIoSudeKNCJaQWq8dKz7nhcL6sAtdQd5lC8GE5FhNiQYpZOXqGspDCwowL6Xf4XbjTDQFTVdwgzO+rXr2zItwoLM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CZzFPWr7; 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="CZzFPWr7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 43C8F1F00ADE; Fri, 22 May 2026 19:43:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478985; bh=SNn+vri9RRR9gMRxnX7erNj8H9djqSG4aGq8GD9k76c=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=CZzFPWr7Lr58yG3gkaYoK8eH4kIKTi3mqmAalxEcoAy21k2VXC6l5s6iI9//wMk4N NxjfmDCvRFrfCz1jGNlEyxIrR1nR64Q1pPQr0C02YZuw+qAK12VEHQPzw8mMfizHf1 OBEOaHBbOye9uVEUSA4voO1oMIZXZ3iHQmaCIH7yUVzAqAC1FBn8DKfSc2Pkf1II7F 1TnuIKom0gnH7UlIEdcOcNcII7os//VP2O2SbGdfBy04hGdakliq5cWLR+MQAT6iSl 8TY54opW13qkBNdrUjLNPSrUxDlx+jAsJTRlVdw7cd14ZqEKhMfORBCttKufE5x346 kbakm9ZvIMmsA== From: Jeff Layton Date: Fri, 22 May 2026 15:42:23 -0400 Subject: [PATCH v5 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-v5-18-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGidRP4f2Dl0NdDmEbDbDRxOvVM/cm1wWYBG aRGlFTddbmJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxogAKCRAADmhBGVaC FfpiD/0ai7GIttvby6Dhm4WScYzubfwm2RUzauT+o2CVq0JxS8i6c/XgL/Yrod7lvl9RVcr2MUO oX53wA1u3Y3duCXZHaaGPmVBxYnPzXjXIX2/ShiHYokNDpEqDi4SrE0v9DFZwwEaX4IBc7IeXgR Z3ylWlKLpc6MzR5Y9mvlEs7kn7agcpCYDEm2rq+F6S87UjAY8X/dp0iEasHD2aLYaU0Ukq8gdXi 1IReD7HHAXOt3ZiqFLHqNmYMKBVt2pD7pxzNe/rG9Cd0jiiORMGroPLAJJTdOEFpUWWTpb8/+h5 qGMDD2clb1tvN8k1tPM9EXVCG6upsu1Caa+cn5fEne/wanDccHR6olLs8fOTKAW+pxyTNalXvTX NlN4Naq/gqZO9yh/r6N8AQa8JkEiPuyubqM5dYOZOpez9SxV94VQsBazUdcVsd2LV0JKxmYyYAN Fh35mrL2jsb5dogEVBQ1fo95ONMrVTSWDr/JX2mWjpqG3TLlfmKdm7/3Qd8l0gkG5uuN+CoUc1q QMABC08ZRl+XaCeH9dDj+wUgM9XUKq9pNWdsz1r+IaDrbJrTuEScGibqG54uzdQPJ8TCr+mPgqz i5khrCNf48V7YVV7qS7m3k9atLje+6kvZ8mlAnl2imgEoly//ZHKuOpI5Sj1tjNn6Qcchpzh9cO By1gayr6w/m39cw== 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:31 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 DEA0B3806A7; Fri, 22 May 2026 19:43:07 +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=1779478992; cv=none; b=chXcgfRPnHPIOB2VJ1Xl6+eUL1u8dHXL8QjXjmOTsXqnkytnUmkNtOHePHUb52Hg0xbWa8qntd7dlr8HsMpb92AbMnx8/QJ1s9cavrU1ifExSAHr9nq/2MLJ6YmHG5Y1xhnI2fyZELF5WaNRko4fBP23qGvSOWSPJ4NzLxFBmE8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478992; c=relaxed/simple; bh=k0EtO5J541KFdHLWERfs+iU6uk2lKGkM05ic+nH1Mbc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HmSoJ8/U/dOXfbApNntUPJel39/MMxbEql+eJgPYuZXMNP3wWamMro+lKLr2A8RooB3NQYC61AVSPWeHql4D5YlWnzm+gRK1Mr33QaQ2VcYV6v9kZmQHH1vWttuxKTnbk6ohQHrzQJqpd12+ixB5EBz1NLcUrSLpZJ8WceoOkX4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IShTygvS; 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="IShTygvS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 33A581F000E9; Fri, 22 May 2026 19:43:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478986; bh=r3WM/Rdns4JIssJHNi4RJwCbBYDGOlePNgzlUCVXveo=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=IShTygvSD+iAtelMs153sfTBe6XXA6QSA5FdRvp/KLFck9Um9ilSZtBsqitqXOY0c qRAus16vLLrEd2nTKdtXTShXNhX3THJrgsziJb6WzHwRQjrXAu2n7o38OCqTpaz9i8 7wZm/sYcR43Ums3nKwlk7+VrzVYqDKL/fPA7lXFKVWfclBCfyOohzOght2DBR8+jzm tVC8izhDlh0kCio/1isEt0pTG2NJpSTKs8Dks5WBZdJmDFwaTSgiFyxiDUVbz2kTxi mHnYWlxsxQaC71ZPfGYkGJdfb63kXzf/S3SvcAkVNax20BkuQknpxAE0R4/3YKVWE8 WWj6RF+3SXcZA== From: Jeff Layton Date: Fri, 22 May 2026 15:42:24 -0400 Subject: [PATCH v5 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-v5-19-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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=k0EtO5J541KFdHLWERfs+iU6uk2lKGkM05ic+nH1Mbc=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGjWI/vpG1tp4TpPxewLW5DaO2gshFL+An0T 3xzmDljecOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxowAKCRAADmhBGVaC FUBoD/90XvP70zECGDaA9LYaUePYXo36GbkrvxUCyhunMN93wKzB82ZY3T/OiwsPD4xxayV4LKa oSklYCAWJ0Yk2WILu4otvgddwxaSsgxP0HoYOQAzm0rwnufKb3P0m4wlofQxGpgHWumX8/KdNY8 Qh2LPkhGWCOhG7v1pWDkeCGiQ2tbcUbblNeGOOgcozRDWRsvn1ahxKtv3fZZG5n1EDYmtdtkaCX IE/GZvHUMMlU5zJQmmeO/oix9GXykZYsUcYhj+Hz4uvACuKiXsb3VRrek9fITYS9SVwuhdlCSRH lAMwVnNcO+JKhEea0NFpsyGn+65L6hk8M9zcC5XkjesD7lP6+BdlqLYtx7o5/DQoCqX0x34UmaD iM1glSx/BevK8iEwJQKVS1/zhsAvwCp932DoVS8mc06JZmjvKLyOOW5hIjS0U1wm+MLcWIsFV3g VYALuqjvb6T9iuKEi9IOHwgiFkQ/Lgf9Rv9pM9afwpuKdsphj0saWnWxqA3soqK6oNypCNeci4C HtN1vd1ld4Y9NiMGP4/XuDni1+W25QNx7KkzG5FjcKzrd/CpxwNU+N6HrbhaZVfzdSHzSIQVlkk 6WijB0d/dZvz7Ze2Mmy8wU5WCDpT6cDYnLWqbZsNtrei8R5Z3O4fWvhKKSIIU0DC9xukt9z0fn4 hlw2CVEdVPz1dIg== 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 eed997d1c88f..ce740a94a634 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9820,6 +9820,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 @@ -9889,6 +9904,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:31 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 C8683388E57; Fri, 22 May 2026 19:43:09 +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=1779478993; cv=none; b=D/HvGMEX/i5f4+H3MWhvFBHUP7l7Nq5JeS2pRrG2Or52f959g5//9pEZmnDQe47WDw/Qd5m3Oehm5QdTW///4Jt0c1x5DsfHuzw29Vvl+9Pu1VRCIoaPmnLt2GcD7LahcOdqc/X7+8b9XysUzDsYsaodO1PQcV4jCAdRJ7szI+I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478993; c=relaxed/simple; bh=t9jrSKxw8DBvKHYaGlpafp9/PesIsxu9ynLOhInymQA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HhKYM0VsIK2YSI8JyITsj4CF4L6oZCpxUyLUFGe2EonE4HY7t3Bje4pmhSqcQdXNcUcKKcnRFiKR3iB+OJwj1yfGINY2yCWsNFeoSRMc7Qw2wlE7saBqCFgVDflEKoQc4KRp+RBUsFwnW6+O4NBFIBXoBkXMHMipEAcwzNJvQh4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cO3GEHDH; 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="cO3GEHDH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 23D941F0155E; Fri, 22 May 2026 19:43:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478988; bh=joa0PwE25gT61noxUy/rusA1r43LI/faaUBqfT44OAc=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=cO3GEHDHsJdEvt3IJoYzIV9Y8ozkFjs2SaOR9fzLXjPA+5a4FvvVSL4C8oLN7bDH7 aKcY1ERvoOJb1sBd79wFWBTf/KXagtukdpvOfDMAZw/KluDl9nhJVKQ2FPoHAecSTX N0SJDYVuCz7YY0+DZmkWnAx30RE6kQjXqlVTeDMn+YZkxK9Tq4VNIe/OabcwCrMmGm vu5NLCfjS7/hJOihFIzrP9qPxIto0gz+sjN7aEQQEPcJTxYg+uiPLum1n5w+h32ana D4ih2CHPlyVqgcwVYISao0cS5JNHTHe9cQS3VWgh/Ih/bekPm2Ha9zLzWS4ggDtgmA x+aMSRGEbNQrg== From: Jeff Layton Date: Fri, 22 May 2026 15:42:25 -0400 Subject: [PATCH v5 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-v5-20-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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=3331; i=jlayton@kernel.org; h=from:subject:message-id; bh=t9jrSKxw8DBvKHYaGlpafp9/PesIsxu9ynLOhInymQA=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGjZPpn+ZYdbMiFMIq/ZaaBNn7PbUH47tdPz ovCDEBr90GJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxowAKCRAADmhBGVaC FROND/9tvDdp6nYJGlCgJ+ZHFiCV1FCNmh1D1u5RILIr8KabT1ocLAtP38D6M4rT7bp7mE/kyKq q8SaBtYk5eCcPTiiXjTrVpWLMu4jrYHe3NIwBGwG+JNOvsawYVetzwiujGYUVDjC+vDdq+E53D3 HEGyagYO1CJIkdOSq16WIxtoLwDFSG8tcceSmsdoYd1SsIUTvQyTZwyE5eVF1HpBRztUchxgrvZ BKEuKpw5DruwTxTJ4bzyzCQ/9hu7X5rltNIVBB/5B0ilG9GiA+p+U/FQTZiHKa35YXZBfq7Q62r HwTHkwA7R7+N9SZnUqMnUgbi/zOexiovXfl3yPSqyJhJBNitfvp1FJkP7Hx+wqYVtS2DL8mfWC8 fPw/uKF1acx5844/RyU5HTRkgfi0z+NAXRqM78+55dY9T3uxR049+kZJe+rXUQCxjw8N+XVmPbJ zyyhADmfICi1kIpK8zGjWjjgMYVNHpobw54REjcFs4MAPacS18mojVZgot4mmtUxQhGXINWKe1w yDe7XK6XHcrB97vWmXunxOAPdFFJ4iUxZeW8EFYMvyjnO35OtashI6+ZJ3dDI+f5i/2BIGolraN oAt0j01JkkCwAC2ZDRz5snPc9WjYT2xk3ZZ1QvOxHRHg2Ovc+Obno+LilzuQVnfRFDR/ikj1jC4 Wn/vdVN6e7TDuVQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Track the union of requested and supported dir attributes in the delegation. In a later patch this will be used to ensure that we 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 ce740a94a634..6c808149f251 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9835,6 +9835,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 @@ -9904,10 +9913,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:31 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 457D3389455; Fri, 22 May 2026 19:43: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=1779478995; cv=none; b=AgPfjgGodorLSR0HNIZSaCSaOokFzFDNuqDenafwT3c9ILCzFrjmKDZNJ4jn6WYYQ9YNQToaauRad+CxQXaqLS5hpiYNoPARNP0+hxY6zEKGsem+o4vyMm3940JJ+Y8zBXkBbWNcwzhkuGZJbWnGycn+ijAX2MyH3QaJbYNsrus= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779478995; c=relaxed/simple; bh=hz3feZ94dD+Z906TmckXoxMlvgUvqfXskuJXRG4kv6U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TU/ZnrUEhS6GhtYLll3wlpSvydZcSIRFKL4pxqKsPU8I87Wz7giUgXg05Axj+cVy6DZbV9h67FRa+xqalsjk2spzA5wW8pWx5LVEqmvPR78pRoqcJzY9udJyDn+KY9ZwEmSa6dtTSSH4i45CQ5M8TRW3ylEMRCIkswCmUEvJv/4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KEywnAun; 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="KEywnAun" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 138F11F00A3D; Fri, 22 May 2026 19:43:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1779478990; bh=mys0ncIaAkG+9pCx8mZR+SvFBHBoSXG73vY0mMvfO2I=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=KEywnAunYTO1WaKuVfOj2fd4kfO8ZPiKlm3UK+aZXb97Q96CSplSfbdbbNMHPK+Vj b/r5JeAK3+xwYKc12uFHpfY/jIOqwl3tfs+07RgdMd9g2O08REFqpRVzDZ9ijc1rf6 GGWRypf6FlY0rq+KeCWj86QrSOlDnHlpq41LhYz9pg0D7V9tksULiIMPZC2XyY9S1T a1CLI5mlXubI7jcu52S4BcBHfsGCIs6+H8vS+6DgpJY3HzU9YNcY9vaOmlFE9ytouG IY21QK9KvWtmfdxeQXkYKpICNtj9Tg/jguNehU6xvwG7OB3y2F//kZKJVf6rWMI9eh tLNEqbKFtgHtw== From: Jeff Layton Date: Fri, 22 May 2026 15:42:26 -0400 Subject: [PATCH v5 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-v5-21-542cddfad576@kernel.org> References: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> In-Reply-To: <20260522-dir-deleg-v5-0-542cddfad576@kernel.org> To: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Jonathan Corbet , Shuah Khan Cc: Steven Rostedt , 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=hz3feZ94dD+Z906TmckXoxMlvgUvqfXskuJXRG4kv6U=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBqELGjy7/5pHWOj5QRrVXwM6vrl86D45JEKSE/B u4vGfF7VHSJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCahCxowAKCRAADmhBGVaC FXmLEADNVFLGkwMWaM3rSzrGEjwrfa80U8IEHUxva1NMhZrcdezYo/ZgifZBkhyZ0ZNZfOAsAJc FuK69pC30Bd/MmKztoAsnssmJU4rLHq60OT6xAQwO6gcFFdcau9CRD44JR/hpk832llgN1m9yMV Vy94qacJKRVhvXnaJkWE41VqGfomTskj8mB1mIMD/w0Bb2EtmB2v3u/MG62J8U56lDueNGJc96U 37MF35cN+3ALs7vt2e08g9MgWn46FyR5nPWGFYHwcZJLv2ffAqYeOJY05o/PB+GuniVoaJUTOHw +RWnwC/k4mBhOxarXtRfibLko+w37PA90s+nbEUwbgE+1W3tUbgujy7Bj8GyEn2fIXATJ2A21vI HurLOChHabHYPicmFoqYJIHVYQXVniiWhdUD3At+lmJWQGXhv4Zl6tTYv71dXCy3mHrbWFb/Dj7 6ia6C0J0X+pWyNwrQfuXa64d7R/uW5yxwXxde4pt4vGYbI8byldrfI1wKM1d8olucifsl49bVmD P8TaDLg+8T9J7XC+bZefAVRzkZHN/aD/9VMw4C3upyDRjyDc5d2y8TMrylCfZALLoVcxRfAGzAf nogGYwIkcuWMLxRjuim7L3FfJboVu/POJ5p86S4OkKYOFl2wXMLWFTvPeDPVtr4KkJA8jIKJCH2 GP7heR04e9yMOIQ== 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 6c808149f251..acddd55a99d8 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3491,10 +3491,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 @@ -3508,7 +3513,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; } @@ -3555,6 +3560,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