diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/sunrpc/netlink.c | 12 | ||||
| -rw-r--r-- | net/sunrpc/netlink.h | 1 | ||||
| -rw-r--r-- | net/sunrpc/svcauth_unix.c | 32 |
3 files changed, 45 insertions, 0 deletions
diff --git a/net/sunrpc/netlink.c b/net/sunrpc/netlink.c index 3ac6b0cac5fe..5ccf0967809c 100644 --- a/net/sunrpc/netlink.c +++ b/net/sunrpc/netlink.c @@ -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[] = { diff --git a/net/sunrpc/netlink.h b/net/sunrpc/netlink.h index 2aec57d27a58..2c1012303d48 100644 --- a/net/sunrpc/netlink.h +++ b/net/sunrpc/netlink.h @@ -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, diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 7703523d4246..64a2658faddb 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -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, |
