History

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.

Jeff Layton committed 7 months ago

Commit 565ee231 parent 01c23055 files · +70 −0Browse files

Unified · Split

5 files
  1. Documentation/netlink/specs/sunrpc_cache.yaml +17 −0
  2. include/uapi/linux/sunrpc_netlink.h +8 −0
  3. net/sunrpc/netlink.c +12 −0
  4. net/sunrpc/netlink.h +1 −0
  5. net/sunrpc/svcauth_unix.c +32 −0
Documentation/netlink/specs/sunrpc_cache.yaml+17−0
@@ -76,6 +76,14 @@ attribute-sets: · 75 unmodified lines
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: · 41 unmodified lines
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+8−0
@@ -59,12 +59,20 @@ enum { · 58 unmodified lines
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+12−0
@@ -49,6 +49,11 @@ static const struct nla_policy sunrpc_unix_gid_set_reqs_nl_policy[SUNRPC_A_UNIX_ · 48 unmodified lines
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[] = { · 24 unmodified lines
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+1−0
@@ -23,6 +23,7 @@ int sunrpc_nl_unix_gid_get_reqs_dumpit(struct sk_buff *skb, · 22 unmodified lines
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+32−0
@@ -818,6 +818,38 @@ int sunrpc_nl_unix_gid_set_reqs_doit(struct sk_buff *skb, · 817 unmodified lines
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,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t