[PATCH 07/14] sunrpc: add a generic netlink family for cache upcalls

Jeff Layton posted 14 patches 3 weeks ago
There is a newer version of this series
Re: [PATCH 07/14] sunrpc: add a generic netlink family for cache upcalls
Posted by Chuck Lever 2 weeks, 4 days ago
On 3/16/26 11:14 AM, Jeff Layton wrote:

> diff --git a/fs/nfsd/netlink.c b/fs/nfsd/netlink.c
> index 4e08c1a6b3943cda5b44c2b64bcf3a00173a08db..81c943345d13db849483bf0d6773458115ff0134 100644
> --- a/fs/nfsd/netlink.c
> +++ b/fs/nfsd/netlink.c
> @@ -59,7 +59,7 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
>  		.cmd		= NFSD_CMD_THREADS_SET,
>  		.doit		= nfsd_nl_threads_set_doit,
>  		.policy		= nfsd_threads_set_nl_policy,
> -		.maxattr	= NFSD_A_SERVER_MAX,
> +		.maxattr	= NFSD_A_SERVER_FH_KEY,
>  		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
>  	},
>  	{

This hunk is clearly not related to adding "a generic netlink family for
cache upcalls". Should I apply it instead to the appropriate FH-signing
patch, which is still in my nfsd-testing branch?


-- 
Chuck Lever
Re: [PATCH 07/14] sunrpc: add a generic netlink family for cache upcalls
Posted by Jeff Layton 2 weeks, 4 days ago
On Thu, 2026-03-19 at 15:14 -0400, Chuck Lever wrote:
> On 3/16/26 11:14 AM, Jeff Layton wrote:
> 
> > diff --git a/fs/nfsd/netlink.c b/fs/nfsd/netlink.c
> > index 4e08c1a6b3943cda5b44c2b64bcf3a00173a08db..81c943345d13db849483bf0d6773458115ff0134 100644
> > --- a/fs/nfsd/netlink.c
> > +++ b/fs/nfsd/netlink.c
> > @@ -59,7 +59,7 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
> >  		.cmd		= NFSD_CMD_THREADS_SET,
> >  		.doit		= nfsd_nl_threads_set_doit,
> >  		.policy		= nfsd_threads_set_nl_policy,
> > -		.maxattr	= NFSD_A_SERVER_MAX,
> > +		.maxattr	= NFSD_A_SERVER_FH_KEY,
> >  		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
> >  	},
> >  	{
> 
> This hunk is clearly not related to adding "a generic netlink family for
> cache upcalls". Should I apply it instead to the appropriate FH-signing
> patch, which is still in my nfsd-testing branch?
> 

I noticed that too. I think this is due to a change in the ynl tool.
The new way seems more correct since the "*_MAX" value is fluid.

If you wanted, we could just regenerate the files with the new tool and
commit those changes first and then layer the new stuff on top.
-- 
Jeff Layton <jlayton@kernel.org>
Re: [PATCH 07/14] sunrpc: add a generic netlink family for cache upcalls
Posted by Chuck Lever 2 weeks, 4 days ago
On 3/19/26 3:19 PM, Jeff Layton wrote:
> On Thu, 2026-03-19 at 15:14 -0400, Chuck Lever wrote:
>> On 3/16/26 11:14 AM, Jeff Layton wrote:
>>
>>> diff --git a/fs/nfsd/netlink.c b/fs/nfsd/netlink.c
>>> index 4e08c1a6b3943cda5b44c2b64bcf3a00173a08db..81c943345d13db849483bf0d6773458115ff0134 100644
>>> --- a/fs/nfsd/netlink.c
>>> +++ b/fs/nfsd/netlink.c
>>> @@ -59,7 +59,7 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
>>>  		.cmd		= NFSD_CMD_THREADS_SET,
>>>  		.doit		= nfsd_nl_threads_set_doit,
>>>  		.policy		= nfsd_threads_set_nl_policy,
>>> -		.maxattr	= NFSD_A_SERVER_MAX,
>>> +		.maxattr	= NFSD_A_SERVER_FH_KEY,
>>>  		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
>>>  	},
>>>  	{
>>
>> This hunk is clearly not related to adding "a generic netlink family for
>> cache upcalls". Should I apply it instead to the appropriate FH-signing
>> patch, which is still in my nfsd-testing branch?
>>
> 
> I noticed that too. I think this is due to a change in the ynl tool.
> The new way seems more correct since the "*_MAX" value is fluid.
> 
> If you wanted, we could just regenerate the files with the new tool and
> commit those changes first and then layer the new stuff on top.

I checked the tool, it hasn't changed.


-- 
Chuck Lever
Re: [PATCH 07/14] sunrpc: add a generic netlink family for cache upcalls
Posted by Chuck Lever 2 weeks, 4 days ago
On 3/19/26 3:20 PM, Chuck Lever wrote:
> On 3/19/26 3:19 PM, Jeff Layton wrote:
>> On Thu, 2026-03-19 at 15:14 -0400, Chuck Lever wrote:
>>> On 3/16/26 11:14 AM, Jeff Layton wrote:
>>>
>>>> diff --git a/fs/nfsd/netlink.c b/fs/nfsd/netlink.c
>>>> index 4e08c1a6b3943cda5b44c2b64bcf3a00173a08db..81c943345d13db849483bf0d6773458115ff0134 100644
>>>> --- a/fs/nfsd/netlink.c
>>>> +++ b/fs/nfsd/netlink.c
>>>> @@ -59,7 +59,7 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
>>>>  		.cmd		= NFSD_CMD_THREADS_SET,
>>>>  		.doit		= nfsd_nl_threads_set_doit,
>>>>  		.policy		= nfsd_threads_set_nl_policy,
>>>> -		.maxattr	= NFSD_A_SERVER_MAX,
>>>> +		.maxattr	= NFSD_A_SERVER_FH_KEY,
>>>>  		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
>>>>  	},
>>>>  	{
>>>
>>> This hunk is clearly not related to adding "a generic netlink family for
>>> cache upcalls". Should I apply it instead to the appropriate FH-signing
>>> patch, which is still in my nfsd-testing branch?
>>>
>>
>> I noticed that too. I think this is due to a change in the ynl tool.
>> The new way seems more correct since the "*_MAX" value is fluid.
>>
>> If you wanted, we could just regenerate the files with the new tool and
>> commit those changes first and then layer the new stuff on top.
> 
> I checked the tool, it hasn't changed.
I think "NFSD: Add a key for signing filehandles" introduced this
anomaly, so I've gone back to that patch and re-ran the tool. This was
the only change that was generated, so I applied it and pushed it to
nfsd-testing.


-- 
Chuck Lever
Re: [PATCH 07/14] sunrpc: add a generic netlink family for cache upcalls
Posted by Chuck Lever 2 weeks, 4 days ago
On 3/16/26 11:14 AM, Jeff Layton wrote:
> The auth.unix.ip and auth.unix.gid caches live in the sunrpc module,
> so they cannot use the nfsd generic netlink family. Create a new
> "sunrpc" generic netlink family with its own "exportd" multicast
> group to support cache upcall notifications for sunrpc-resident
> caches.
> 
> Define a YAML spec (sunrpc_cache.yaml) with a cache-type enum
> (ip_map, unix_gid), a cache-notify multicast event, and the
> corresponding uapi header.
> 
> Implement sunrpc_cache_notify() which mirrors the nfsd_cache_notify()
> pattern: check for listeners on the exportd multicast group, build
> and send SUNRPC_CMD_CACHE_NOTIFY with the cache-type attribute.
> 
> Register/unregister the sunrpc_nl_family in init_sunrpc() and
> cleanup_sunrpc().
> 
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
>  Documentation/netlink/specs/sunrpc_cache.yaml | 40 ++++++++++++++++
>  fs/nfsd/netlink.c                             |  2 +-
>  include/uapi/linux/sunrpc_netlink.h           | 35 ++++++++++++++
>  net/sunrpc/Makefile                           |  2 +-
>  net/sunrpc/netlink.c                          | 66 +++++++++++++++++++++++++++
>  net/sunrpc/netlink.h                          | 25 ++++++++++
>  net/sunrpc/sunrpc_syms.c                      | 10 ++++
>  7 files changed, 178 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/netlink/specs/sunrpc_cache.yaml b/Documentation/netlink/specs/sunrpc_cache.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..f4aa699598bca9ce0215bbc418d9ddcae25c0110
> --- /dev/null
> +++ b/Documentation/netlink/specs/sunrpc_cache.yaml
> @@ -0,0 +1,40 @@
> +# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
> +---
> +name: sunrpc
> +protocol: genetlink
> +uapi-header: linux/sunrpc_netlink.h
> +
> +doc: SUNRPC cache upcall support over generic netlink.
> +
> +definitions:
> +  -
> +    type: flags
> +    name: cache-type
> +    entries: [ip_map, unix_gid]
> +
> +attribute-sets:
> +  -
> +    name: cache-notify
> +    attributes:
> +      -
> +        name: cache-type
> +        type: u32
> +        enum: cache-type
> +
> +operations:
> +  list:
> +    -
> +      name: cache-notify
> +      doc: Notification that there are cache requests that need servicing
> +      attribute-set: cache-notify
> +      mcgrp: exportd
> +      event:
> +        attributes:
> +          - cache-type
> +
> +mcast-groups:
> +  list:
> +    -
> +      name: none
> +    -
> +      name: exportd
> diff --git a/fs/nfsd/netlink.c b/fs/nfsd/netlink.c
> index 4e08c1a6b3943cda5b44c2b64bcf3a00173a08db..81c943345d13db849483bf0d6773458115ff0134 100644
> --- a/fs/nfsd/netlink.c
> +++ b/fs/nfsd/netlink.c
> @@ -59,7 +59,7 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
>  		.cmd		= NFSD_CMD_THREADS_SET,
>  		.doit		= nfsd_nl_threads_set_doit,
>  		.policy		= nfsd_threads_set_nl_policy,
> -		.maxattr	= NFSD_A_SERVER_MAX,
> +		.maxattr	= NFSD_A_SERVER_FH_KEY,
>  		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
>  	},
>  	{
> diff --git a/include/uapi/linux/sunrpc_netlink.h b/include/uapi/linux/sunrpc_netlink.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..6135d9b3eef155a9192d9710c8c690283ec49073
> --- /dev/null
> +++ b/include/uapi/linux/sunrpc_netlink.h
> @@ -0,0 +1,35 @@
> +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
> +/* Do not edit directly, auto-generated from: */
> +/*	Documentation/netlink/specs/sunrpc_cache.yaml */
> +/* YNL-GEN uapi header */
> +/* To regenerate run: tools/net/ynl/ynl-regen.sh */
> +
> +#ifndef _UAPI_LINUX_SUNRPC_NETLINK_H
> +#define _UAPI_LINUX_SUNRPC_NETLINK_H
> +
> +#define SUNRPC_FAMILY_NAME	"sunrpc"
> +#define SUNRPC_FAMILY_VERSION	1
> +
> +enum sunrpc_cache_type {
> +	SUNRPC_CACHE_TYPE_IP_MAP = 1,
> +	SUNRPC_CACHE_TYPE_UNIX_GID = 2,
> +};
> +
> +enum {
> +	SUNRPC_A_CACHE_NOTIFY_CACHE_TYPE = 1,
> +
> +	__SUNRPC_A_CACHE_NOTIFY_MAX,
> +	SUNRPC_A_CACHE_NOTIFY_MAX = (__SUNRPC_A_CACHE_NOTIFY_MAX - 1)
> +};
> +
> +enum {
> +	SUNRPC_CMD_CACHE_NOTIFY = 1,
> +
> +	__SUNRPC_CMD_MAX,
> +	SUNRPC_CMD_MAX = (__SUNRPC_CMD_MAX - 1)
> +};
> +
> +#define SUNRPC_MCGRP_NONE	"none"
> +#define SUNRPC_MCGRP_EXPORTD	"exportd"
> +
> +#endif /* _UAPI_LINUX_SUNRPC_NETLINK_H */
> diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
> index f89c10fe7e6acc71d47273200d85425a2891a08a..96727df3aa85435a2de63a8483eab9d75d5b3495 100644
> --- a/net/sunrpc/Makefile
> +++ b/net/sunrpc/Makefile
> @@ -14,7 +14,7 @@ sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
>  	    addr.o rpcb_clnt.o timer.o xdr.o \
>  	    sunrpc_syms.o cache.o rpc_pipe.o sysfs.o \
>  	    svc_xprt.o \
> -	    xprtmultipath.o
> +	    xprtmultipath.o netlink.o
>  sunrpc-$(CONFIG_SUNRPC_DEBUG) += debugfs.o
>  sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o
>  sunrpc-$(CONFIG_PROC_FS) += stats.o
> diff --git a/net/sunrpc/netlink.c b/net/sunrpc/netlink.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..e59ee82dfab358fc367045d9f04c394000c812ec
> --- /dev/null
> +++ b/net/sunrpc/netlink.c
> @@ -0,0 +1,66 @@
> +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
> +/* Do not edit directly, auto-generated from: */
> +/*	Documentation/netlink/specs/sunrpc_cache.yaml */
> +/* YNL-GEN kernel source */
> +/* To regenerate run: tools/net/ynl/ynl-regen.sh */
> +
> +#include <net/netlink.h>
> +#include <net/genetlink.h>
> +#include <linux/sunrpc/cache.h>
> +
> +#include "netlink.h"
> +
> +#include <uapi/linux/sunrpc_netlink.h>
> +
> +/* Ops table for sunrpc */
> +static const struct genl_split_ops sunrpc_nl_ops[] = {
> +};
> +
> +static const struct genl_multicast_group sunrpc_nl_mcgrps[] = {
> +	[SUNRPC_NLGRP_NONE] = { "none", },
> +	[SUNRPC_NLGRP_EXPORTD] = { "exportd", },
> +};
> +
> +struct genl_family sunrpc_nl_family __ro_after_init = {
> +	.name		= SUNRPC_FAMILY_NAME,
> +	.version	= SUNRPC_FAMILY_VERSION,
> +	.netnsok	= true,
> +	.parallel_ops	= true,
> +	.module		= THIS_MODULE,
> +	.split_ops	= sunrpc_nl_ops,
> +	.n_split_ops	= ARRAY_SIZE(sunrpc_nl_ops),
> +	.mcgrps		= sunrpc_nl_mcgrps,
> +	.n_mcgrps	= ARRAY_SIZE(sunrpc_nl_mcgrps),
> +};
> +
> +int sunrpc_cache_notify(struct cache_detail *cd, struct cache_head *h,
> +			u32 cache_type)
> +{
> +	struct genlmsghdr *hdr;
> +	struct sk_buff *msg;
> +
> +	if (!genl_has_listeners(&sunrpc_nl_family, cd->net,
> +				SUNRPC_NLGRP_EXPORTD))
> +		return -ENOLINK;
> +
> +	msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
> +	if (!msg)
> +		return -ENOMEM;
> +
> +	hdr = genlmsg_put(msg, 0, 0, &sunrpc_nl_family, 0,
> +			  SUNRPC_CMD_CACHE_NOTIFY);
> +	if (!hdr) {
> +		nlmsg_free(msg);
> +		return -ENOMEM;
> +	}
> +
> +	if (nla_put_u32(msg, SUNRPC_A_CACHE_NOTIFY_CACHE_TYPE, cache_type)) {
> +		nlmsg_free(msg);
> +		return -ENOMEM;
> +	}
> +
> +	genlmsg_end(msg, hdr);
> +	return genlmsg_multicast_netns(&sunrpc_nl_family, cd->net, msg, 0,
> +				       SUNRPC_NLGRP_EXPORTD, GFP_KERNEL);
> +}
> +EXPORT_SYMBOL_GPL(sunrpc_cache_notify);

Is sunrpc_cache_notify() hand-written? If it is, can you find another
initial landing place for it (I think it is moved out in a later patch)?


> diff --git a/net/sunrpc/netlink.h b/net/sunrpc/netlink.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..efb05f87b89513fe738964a1b27637a09f9b88a9
> --- /dev/null
> +++ b/net/sunrpc/netlink.h
> @@ -0,0 +1,25 @@
> +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
> +/* Do not edit directly, auto-generated from: */
> +/*	Documentation/netlink/specs/sunrpc_cache.yaml */
> +/* YNL-GEN kernel header */
> +/* To regenerate run: tools/net/ynl/ynl-regen.sh */
> +
> +#ifndef _LINUX_SUNRPC_GEN_H
> +#define _LINUX_SUNRPC_GEN_H
> +
> +#include <net/netlink.h>
> +#include <net/genetlink.h>
> +
> +#include <uapi/linux/sunrpc_netlink.h>
> +
> +enum {
> +	SUNRPC_NLGRP_NONE,
> +	SUNRPC_NLGRP_EXPORTD,
> +};
> +
> +extern struct genl_family sunrpc_nl_family;
> +
> +int sunrpc_cache_notify(struct cache_detail *cd, struct cache_head *h,
> +			u32 cache_type);

Ditto...


> +
> +#endif /* _LINUX_SUNRPC_GEN_H */
> diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
> index bab6cab2940524a970422b62b3fa4212c61c4f43..ab88ce46afb556cb0a397fe5c9df3901813ad01e 100644
> --- a/net/sunrpc/sunrpc_syms.c
> +++ b/net/sunrpc/sunrpc_syms.c
> @@ -23,9 +23,12 @@
>  #include <linux/sunrpc/rpc_pipe_fs.h>
>  #include <linux/sunrpc/xprtsock.h>
>  
> +#include <net/genetlink.h>
> +
>  #include "sunrpc.h"
>  #include "sysfs.h"
>  #include "netns.h"
> +#include "netlink.h"
>  
>  unsigned int sunrpc_net_id;
>  EXPORT_SYMBOL_GPL(sunrpc_net_id);
> @@ -108,6 +111,10 @@ init_sunrpc(void)
>  	if (err)
>  		goto out5;
>  
> +	err = genl_register_family(&sunrpc_nl_family);
> +	if (err)
> +		goto out6;
> +
>  	sunrpc_debugfs_init();
>  #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
>  	rpc_register_sysctl();
> @@ -116,6 +123,8 @@ init_sunrpc(void)
>  	init_socket_xprt();	/* clnt sock transport */
>  	return 0;
>  
> +out6:
> +	rpc_sysfs_exit();
>  out5:
>  	unregister_rpc_pipefs();
>  out4:
> @@ -131,6 +140,7 @@ init_sunrpc(void)
>  static void __exit
>  cleanup_sunrpc(void)
>  {
> +	genl_unregister_family(&sunrpc_nl_family);
>  	rpc_sysfs_exit();
>  	rpc_cleanup_clids();
>  	xprt_cleanup_ids();
> 


-- 
Chuck Lever