Skip to content

Commit 565ee23

Browse files
jtlaytonchucklever
authored andcommitted
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>
1 parent 01c2305 commit 565ee23

5 files changed

Lines changed: 70 additions & 0 deletions

File tree

Documentation/netlink/specs/sunrpc_cache.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ attribute-sets:
7676
type: nest
7777
nested-attributes: unix-gid
7878
multi-attr: true
79+
-
80+
name: cache-flush
81+
attributes:
82+
-
83+
name: mask
84+
type: u32
85+
enum: cache-type
86+
enum-as-flags: true
7987

8088
operations:
8189
list:
@@ -123,6 +131,15 @@ operations:
123131
request:
124132
attributes:
125133
- requests
134+
-
135+
name: cache-flush
136+
doc: Flush sunrpc caches (ip_map and/or unix_gid)
137+
attribute-set: cache-flush
138+
flags: [admin-perm]
139+
do:
140+
request:
141+
attributes:
142+
- mask
126143

127144
mcast-groups:
128145
list:

include/uapi/linux/sunrpc_netlink.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,20 @@ enum {
5959
SUNRPC_A_UNIX_GID_REQS_MAX = (__SUNRPC_A_UNIX_GID_REQS_MAX - 1)
6060
};
6161

62+
enum {
63+
SUNRPC_A_CACHE_FLUSH_MASK = 1,
64+
65+
__SUNRPC_A_CACHE_FLUSH_MAX,
66+
SUNRPC_A_CACHE_FLUSH_MAX = (__SUNRPC_A_CACHE_FLUSH_MAX - 1)
67+
};
68+
6269
enum {
6370
SUNRPC_CMD_CACHE_NOTIFY = 1,
6471
SUNRPC_CMD_IP_MAP_GET_REQS,
6572
SUNRPC_CMD_IP_MAP_SET_REQS,
6673
SUNRPC_CMD_UNIX_GID_GET_REQS,
6774
SUNRPC_CMD_UNIX_GID_SET_REQS,
75+
SUNRPC_CMD_CACHE_FLUSH,
6876

6977
__SUNRPC_CMD_MAX,
7078
SUNRPC_CMD_MAX = (__SUNRPC_CMD_MAX - 1)

net/sunrpc/netlink.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ static const struct nla_policy sunrpc_unix_gid_set_reqs_nl_policy[SUNRPC_A_UNIX_
4949
[SUNRPC_A_UNIX_GID_REQS_REQUESTS] = NLA_POLICY_NESTED(sunrpc_unix_gid_nl_policy),
5050
};
5151

52+
/* SUNRPC_CMD_CACHE_FLUSH - do */
53+
static const struct nla_policy sunrpc_cache_flush_nl_policy[SUNRPC_A_CACHE_FLUSH_MASK + 1] = {
54+
[SUNRPC_A_CACHE_FLUSH_MASK] = NLA_POLICY_MASK(NLA_U32, 0x3),
55+
};
56+
5257
/* Ops table for sunrpc */
5358
static const struct genl_split_ops sunrpc_nl_ops[] = {
5459
{
@@ -79,6 +84,13 @@ static const struct genl_split_ops sunrpc_nl_ops[] = {
7984
.maxattr = SUNRPC_A_UNIX_GID_REQS_REQUESTS,
8085
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
8186
},
87+
{
88+
.cmd = SUNRPC_CMD_CACHE_FLUSH,
89+
.doit = sunrpc_nl_cache_flush_doit,
90+
.policy = sunrpc_cache_flush_nl_policy,
91+
.maxattr = SUNRPC_A_CACHE_FLUSH_MASK,
92+
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
93+
},
8294
};
8395

8496
static const struct genl_multicast_group sunrpc_nl_mcgrps[] = {

net/sunrpc/netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ int sunrpc_nl_unix_gid_get_reqs_dumpit(struct sk_buff *skb,
2323
struct netlink_callback *cb);
2424
int sunrpc_nl_unix_gid_set_reqs_doit(struct sk_buff *skb,
2525
struct genl_info *info);
26+
int sunrpc_nl_cache_flush_doit(struct sk_buff *skb, struct genl_info *info);
2627

2728
enum {
2829
SUNRPC_NLGRP_NONE,

net/sunrpc/svcauth_unix.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,38 @@ int sunrpc_nl_unix_gid_set_reqs_doit(struct sk_buff *skb,
818818
return ret;
819819
}
820820

821+
/**
822+
* sunrpc_nl_cache_flush_doit - flush sunrpc caches via netlink
823+
* @skb: reply buffer
824+
* @info: netlink metadata and command arguments
825+
*
826+
* Flush the ip_map and/or unix_gid caches. If SUNRPC_A_CACHE_FLUSH_MASK
827+
* is provided, only flush the caches indicated by the bitmask (bit 1 =
828+
* ip_map, bit 2 = unix_gid). If omitted, flush both.
829+
*
830+
* Return 0 on success or a negative errno.
831+
*/
832+
int sunrpc_nl_cache_flush_doit(struct sk_buff *skb, struct genl_info *info)
833+
{
834+
struct sunrpc_net *sn;
835+
u32 mask = ~0U;
836+
837+
sn = net_generic(genl_info_net(info), sunrpc_net_id);
838+
839+
if (info->attrs[SUNRPC_A_CACHE_FLUSH_MASK])
840+
mask = nla_get_u32(info->attrs[SUNRPC_A_CACHE_FLUSH_MASK]);
841+
842+
if ((mask & SUNRPC_CACHE_TYPE_IP_MAP) &&
843+
sn->ip_map_cache)
844+
cache_purge(sn->ip_map_cache);
845+
846+
if ((mask & SUNRPC_CACHE_TYPE_UNIX_GID) &&
847+
sn->unix_gid_cache)
848+
cache_purge(sn->unix_gid_cache);
849+
850+
return 0;
851+
}
852+
821853
static const struct cache_detail unix_gid_cache_template = {
822854
.owner = THIS_MODULE,
823855
.hash_size = GID_HASHMAX,

0 commit comments

Comments
 (0)