Skip to content

Commit 70b7e35

Browse files
jtlaytonchucklever
authored andcommitted
nfsd: add NFSD_CMD_CACHE_FLUSH netlink command
Add a new NFSD_CMD_CACHE_FLUSH generic netlink command that allows userspace to flush the nfsd export caches (svc_export and expkey) without writing to /proc/net/rpc/*/flush. An optional NFSD_A_CACHE_FLUSH_MASK u32 attribute selects which caches to flush (bit 1 = svc_export, bit 2 = expkey). If the attribute is omitted, all nfsd 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 565ee23 commit 70b7e35

5 files changed

Lines changed: 74 additions & 0 deletions

File tree

Documentation/netlink/specs/nfsd.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,14 @@ attribute-sets:
293293
type: nest
294294
nested-attributes: expkey
295295
multi-attr: true
296+
-
297+
name: cache-flush
298+
attributes:
299+
-
300+
name: mask
301+
type: u32
302+
enum: cache-type
303+
enum-as-flags: true
296304

297305
operations:
298306
list:
@@ -438,6 +446,15 @@ operations:
438446
request:
439447
attributes:
440448
- requests
449+
-
450+
name: cache-flush
451+
doc: Flush nfsd caches (svc_export and/or expkey)
452+
attribute-set: cache-flush
453+
flags: [admin-perm]
454+
do:
455+
request:
456+
attributes:
457+
- mask
441458

442459
mcast-groups:
443460
list:

fs/nfsd/netlink.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ static const struct nla_policy nfsd_expkey_set_reqs_nl_policy[NFSD_A_EXPKEY_REQS
108108
[NFSD_A_EXPKEY_REQS_REQUESTS] = NLA_POLICY_NESTED(nfsd_expkey_nl_policy),
109109
};
110110

111+
/* NFSD_CMD_CACHE_FLUSH - do */
112+
static const struct nla_policy nfsd_cache_flush_nl_policy[NFSD_A_CACHE_FLUSH_MASK + 1] = {
113+
[NFSD_A_CACHE_FLUSH_MASK] = NLA_POLICY_MASK(NLA_U32, 0x3),
114+
};
115+
111116
/* Ops table for nfsd */
112117
static const struct genl_split_ops nfsd_nl_ops[] = {
113118
{
@@ -191,6 +196,13 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
191196
.maxattr = NFSD_A_EXPKEY_REQS_REQUESTS,
192197
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
193198
},
199+
{
200+
.cmd = NFSD_CMD_CACHE_FLUSH,
201+
.doit = nfsd_nl_cache_flush_doit,
202+
.policy = nfsd_cache_flush_nl_policy,
203+
.maxattr = NFSD_A_CACHE_FLUSH_MASK,
204+
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
205+
},
194206
};
195207

196208
static const struct genl_multicast_group nfsd_nl_mcgrps[] = {

fs/nfsd/netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ int nfsd_nl_svc_export_set_reqs_doit(struct sk_buff *skb,
3838
int nfsd_nl_expkey_get_reqs_dumpit(struct sk_buff *skb,
3939
struct netlink_callback *cb);
4040
int nfsd_nl_expkey_set_reqs_doit(struct sk_buff *skb, struct genl_info *info);
41+
int nfsd_nl_cache_flush_doit(struct sk_buff *skb, struct genl_info *info);
4142

4243
enum {
4344
NFSD_NLGRP_NONE,

fs/nfsd/nfsctl.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/ctype.h>
1111
#include <linux/fs_context.h>
1212

13+
#include <linux/sunrpc/cache.h>
1314
#include <linux/sunrpc/svcsock.h>
1415
#include <linux/lockd/bind.h>
1516
#include <linux/sunrpc/addr.h>
@@ -2212,6 +2213,41 @@ int nfsd_nl_pool_mode_get_doit(struct sk_buff *skb, struct genl_info *info)
22122213
return err;
22132214
}
22142215

2216+
/**
2217+
* nfsd_nl_cache_flush_doit - flush nfsd caches via netlink
2218+
* @skb: reply buffer
2219+
* @info: netlink metadata and command arguments
2220+
*
2221+
* Flush the svc_export and/or expkey caches. If NFSD_A_CACHE_FLUSH_MASK
2222+
* is provided, only flush the caches indicated by the bitmask (bit 0 =
2223+
* svc_export, bit 1 = expkey). If omitted, flush both.
2224+
*
2225+
* Return 0 on success or a negative errno.
2226+
*/
2227+
int nfsd_nl_cache_flush_doit(struct sk_buff *skb, struct genl_info *info)
2228+
{
2229+
struct net *net = genl_info_net(info);
2230+
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
2231+
u32 mask = ~0U;
2232+
2233+
if (info->attrs[NFSD_A_CACHE_FLUSH_MASK])
2234+
mask = nla_get_u32(info->attrs[NFSD_A_CACHE_FLUSH_MASK]);
2235+
2236+
mutex_lock(&nfsd_mutex);
2237+
2238+
if ((mask & NFSD_CACHE_TYPE_SVC_EXPORT) &&
2239+
nn->svc_export_cache)
2240+
cache_purge(nn->svc_export_cache);
2241+
2242+
if ((mask & NFSD_CACHE_TYPE_EXPKEY) &&
2243+
nn->svc_expkey_cache)
2244+
cache_purge(nn->svc_expkey_cache);
2245+
2246+
mutex_unlock(&nfsd_mutex);
2247+
2248+
return 0;
2249+
}
2250+
22152251
int nfsd_cache_notify(struct cache_detail *cd, struct cache_head *h, u32 cache_type)
22162252
{
22172253
struct genlmsghdr *hdr;

include/uapi/linux/nfsd_netlink.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,13 @@ enum {
197197
NFSD_A_EXPKEY_REQS_MAX = (__NFSD_A_EXPKEY_REQS_MAX - 1)
198198
};
199199

200+
enum {
201+
NFSD_A_CACHE_FLUSH_MASK = 1,
202+
203+
__NFSD_A_CACHE_FLUSH_MAX,
204+
NFSD_A_CACHE_FLUSH_MAX = (__NFSD_A_CACHE_FLUSH_MAX - 1)
205+
};
206+
200207
enum {
201208
NFSD_CMD_RPC_STATUS_GET = 1,
202209
NFSD_CMD_THREADS_SET,
@@ -212,6 +219,7 @@ enum {
212219
NFSD_CMD_SVC_EXPORT_SET_REQS,
213220
NFSD_CMD_EXPKEY_GET_REQS,
214221
NFSD_CMD_EXPKEY_SET_REQS,
222+
NFSD_CMD_CACHE_FLUSH,
215223

216224
__NFSD_CMD_MAX,
217225
NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)

0 commit comments

Comments
 (0)