mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-06-21 15:43:21 +02:00
sunrpc: add a generic netlink family for cache upcalls
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() in cache.c, which checks for listeners on the exportd multicast group, builds and sends a SUNRPC_CMD_CACHE_NOTIFY message 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> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
@@ -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
|
||||
@@ -256,6 +256,8 @@ int sunrpc_cache_requests_snapshot(struct cache_detail *cd,
|
||||
struct cache_head **items,
|
||||
u64 *seqnos, int max,
|
||||
u64 min_seqno);
|
||||
int sunrpc_cache_notify(struct cache_detail *cd, struct cache_head *h,
|
||||
u32 cache_type);
|
||||
|
||||
/* Must store cache_detail in seq_file->private if using next three functions */
|
||||
extern void *cache_seq_start_rcu(struct seq_file *file, loff_t *pos);
|
||||
|
||||
@@ -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 */
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -33,9 +33,11 @@
|
||||
#include <linux/sunrpc/cache.h>
|
||||
#include <linux/sunrpc/stats.h>
|
||||
#include <linux/sunrpc/rpc_pipe_fs.h>
|
||||
#include <net/genetlink.h>
|
||||
#include <trace/events/sunrpc.h>
|
||||
|
||||
#include "netns.h"
|
||||
#include "netlink.h"
|
||||
#include "fail.h"
|
||||
|
||||
#define RPCDBG_FACILITY RPCDBG_CACHE
|
||||
@@ -1963,3 +1965,45 @@ int sunrpc_cache_requests_snapshot(struct cache_detail *cd,
|
||||
return i;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sunrpc_cache_requests_snapshot);
|
||||
|
||||
/**
|
||||
* sunrpc_cache_notify - send a netlink notification for a cache event
|
||||
* @cd: cache_detail for the cache
|
||||
* @h: cache_head entry (unused, reserved for future use)
|
||||
* @cache_type: cache type identifier (e.g. SUNRPC_CACHE_TYPE_UNIX_GID)
|
||||
*
|
||||
* Sends a SUNRPC_CMD_CACHE_NOTIFY multicast message on the "exportd"
|
||||
* group if any listeners are present. Returns 0 on success or a
|
||||
* negative errno.
|
||||
*/
|
||||
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(nla_total_size(sizeof(u32)), 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);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// 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),
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
/* 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;
|
||||
|
||||
#endif /* _LINUX_SUNRPC_GEN_H */
|
||||
@@ -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 @@ out:
|
||||
static void __exit
|
||||
cleanup_sunrpc(void)
|
||||
{
|
||||
genl_unregister_family(&sunrpc_nl_family);
|
||||
rpc_sysfs_exit();
|
||||
rpc_cleanup_clids();
|
||||
xprt_cleanup_ids();
|
||||
|
||||
Reference in New Issue
Block a user