mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
sunrpc: add SUNRPC_CMD_CACHE_FLUSH netlink command
Add a new SUNRPC_CMD_CACHE_FLUSH generic netlink command that allows userspace to flush the sunrpc auth caches (ip_map and unix_gid) without writing to /proc/net/rpc/*/flush. An optional SUNRPC_A_CACHE_FLUSH_MASK u32 attribute selects which caches to flush (bit 1 = ip_map, bit 2 = unix_gid). If the attribute is omitted, all sunrpc caches are flushed. This is used by exportfs to replace its /proc-based cache_flush() with a netlink equivalent, with /proc fallback for older kernels. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
@@ -76,6 +76,14 @@ attribute-sets:
|
||||
type: nest
|
||||
nested-attributes: unix-gid
|
||||
multi-attr: true
|
||||
-
|
||||
name: cache-flush
|
||||
attributes:
|
||||
-
|
||||
name: mask
|
||||
type: u32
|
||||
enum: cache-type
|
||||
enum-as-flags: true
|
||||
|
||||
operations:
|
||||
list:
|
||||
@@ -123,6 +131,15 @@ operations:
|
||||
request:
|
||||
attributes:
|
||||
- requests
|
||||
-
|
||||
name: cache-flush
|
||||
doc: Flush sunrpc caches (ip_map and/or unix_gid)
|
||||
attribute-set: cache-flush
|
||||
flags: [admin-perm]
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
- mask
|
||||
|
||||
mcast-groups:
|
||||
list:
|
||||
|
||||
@@ -59,12 +59,20 @@ enum {
|
||||
SUNRPC_A_UNIX_GID_REQS_MAX = (__SUNRPC_A_UNIX_GID_REQS_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
SUNRPC_A_CACHE_FLUSH_MASK = 1,
|
||||
|
||||
__SUNRPC_A_CACHE_FLUSH_MAX,
|
||||
SUNRPC_A_CACHE_FLUSH_MAX = (__SUNRPC_A_CACHE_FLUSH_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
SUNRPC_CMD_CACHE_NOTIFY = 1,
|
||||
SUNRPC_CMD_IP_MAP_GET_REQS,
|
||||
SUNRPC_CMD_IP_MAP_SET_REQS,
|
||||
SUNRPC_CMD_UNIX_GID_GET_REQS,
|
||||
SUNRPC_CMD_UNIX_GID_SET_REQS,
|
||||
SUNRPC_CMD_CACHE_FLUSH,
|
||||
|
||||
__SUNRPC_CMD_MAX,
|
||||
SUNRPC_CMD_MAX = (__SUNRPC_CMD_MAX - 1)
|
||||
|
||||
@@ -49,6 +49,11 @@ static const struct nla_policy sunrpc_unix_gid_set_reqs_nl_policy[SUNRPC_A_UNIX_
|
||||
[SUNRPC_A_UNIX_GID_REQS_REQUESTS] = NLA_POLICY_NESTED(sunrpc_unix_gid_nl_policy),
|
||||
};
|
||||
|
||||
/* SUNRPC_CMD_CACHE_FLUSH - do */
|
||||
static const struct nla_policy sunrpc_cache_flush_nl_policy[SUNRPC_A_CACHE_FLUSH_MASK + 1] = {
|
||||
[SUNRPC_A_CACHE_FLUSH_MASK] = NLA_POLICY_MASK(NLA_U32, 0x3),
|
||||
};
|
||||
|
||||
/* Ops table for sunrpc */
|
||||
static const struct genl_split_ops sunrpc_nl_ops[] = {
|
||||
{
|
||||
@@ -79,6 +84,13 @@ static const struct genl_split_ops sunrpc_nl_ops[] = {
|
||||
.maxattr = SUNRPC_A_UNIX_GID_REQS_REQUESTS,
|
||||
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
|
||||
},
|
||||
{
|
||||
.cmd = SUNRPC_CMD_CACHE_FLUSH,
|
||||
.doit = sunrpc_nl_cache_flush_doit,
|
||||
.policy = sunrpc_cache_flush_nl_policy,
|
||||
.maxattr = SUNRPC_A_CACHE_FLUSH_MASK,
|
||||
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct genl_multicast_group sunrpc_nl_mcgrps[] = {
|
||||
|
||||
@@ -23,6 +23,7 @@ int sunrpc_nl_unix_gid_get_reqs_dumpit(struct sk_buff *skb,
|
||||
struct netlink_callback *cb);
|
||||
int sunrpc_nl_unix_gid_set_reqs_doit(struct sk_buff *skb,
|
||||
struct genl_info *info);
|
||||
int sunrpc_nl_cache_flush_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
|
||||
enum {
|
||||
SUNRPC_NLGRP_NONE,
|
||||
|
||||
@@ -818,6 +818,38 @@ int sunrpc_nl_unix_gid_set_reqs_doit(struct sk_buff *skb,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* sunrpc_nl_cache_flush_doit - flush sunrpc caches via netlink
|
||||
* @skb: reply buffer
|
||||
* @info: netlink metadata and command arguments
|
||||
*
|
||||
* Flush the ip_map and/or unix_gid caches. If SUNRPC_A_CACHE_FLUSH_MASK
|
||||
* is provided, only flush the caches indicated by the bitmask (bit 1 =
|
||||
* ip_map, bit 2 = unix_gid). If omitted, flush both.
|
||||
*
|
||||
* Return 0 on success or a negative errno.
|
||||
*/
|
||||
int sunrpc_nl_cache_flush_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct sunrpc_net *sn;
|
||||
u32 mask = ~0U;
|
||||
|
||||
sn = net_generic(genl_info_net(info), sunrpc_net_id);
|
||||
|
||||
if (info->attrs[SUNRPC_A_CACHE_FLUSH_MASK])
|
||||
mask = nla_get_u32(info->attrs[SUNRPC_A_CACHE_FLUSH_MASK]);
|
||||
|
||||
if ((mask & SUNRPC_CACHE_TYPE_IP_MAP) &&
|
||||
sn->ip_map_cache)
|
||||
cache_purge(sn->ip_map_cache);
|
||||
|
||||
if ((mask & SUNRPC_CACHE_TYPE_UNIX_GID) &&
|
||||
sn->unix_gid_cache)
|
||||
cache_purge(sn->unix_gid_cache);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct cache_detail unix_gid_cache_template = {
|
||||
.owner = THIS_MODULE,
|
||||
.hash_size = GID_HASHMAX,
|
||||
|
||||
Reference in New Issue
Block a user