nfsd: new netlink ops to get/set server pool_mode

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

authored by Jeff Layton and committed by Chuck Lever 00506072 5f71f3c3

+113
+27
Documentation/netlink/specs/nfsd.yaml
··· 115 115 type: nest 116 116 nested-attributes: sock 117 117 multi-attr: true 118 + - 119 + name: pool-mode 120 + attributes: 121 + - 122 + name: mode 123 + type: string 124 + - 125 + name: npools 126 + type: u32 118 127 119 128 operations: 120 129 list: ··· 204 195 reply: 205 196 attributes: 206 197 - addr 198 + - 199 + name: pool-mode-set 200 + doc: set the current server pool-mode 201 + attribute-set: pool-mode 202 + flags: [ admin-perm ] 203 + do: 204 + request: 205 + attributes: 206 + - mode 207 + - 208 + name: pool-mode-get 209 + doc: get info about server pool-mode 210 + attribute-set: pool-mode 211 + do: 212 + reply: 213 + attributes: 214 + - mode 215 + - npools
+17
fs/nfsd/netlink.c
··· 40 40 [NFSD_A_SERVER_SOCK_ADDR] = NLA_POLICY_NESTED(nfsd_sock_nl_policy), 41 41 }; 42 42 43 + /* NFSD_CMD_POOL_MODE_SET - do */ 44 + static const struct nla_policy nfsd_pool_mode_set_nl_policy[NFSD_A_POOL_MODE_MODE + 1] = { 45 + [NFSD_A_POOL_MODE_MODE] = { .type = NLA_NUL_STRING, }, 46 + }; 47 + 43 48 /* Ops table for nfsd */ 44 49 static const struct genl_split_ops nfsd_nl_ops[] = { 45 50 { ··· 86 81 { 87 82 .cmd = NFSD_CMD_LISTENER_GET, 88 83 .doit = nfsd_nl_listener_get_doit, 84 + .flags = GENL_CMD_CAP_DO, 85 + }, 86 + { 87 + .cmd = NFSD_CMD_POOL_MODE_SET, 88 + .doit = nfsd_nl_pool_mode_set_doit, 89 + .policy = nfsd_pool_mode_set_nl_policy, 90 + .maxattr = NFSD_A_POOL_MODE_MODE, 91 + .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, 92 + }, 93 + { 94 + .cmd = NFSD_CMD_POOL_MODE_GET, 95 + .doit = nfsd_nl_pool_mode_get_doit, 89 96 .flags = GENL_CMD_CAP_DO, 90 97 }, 91 98 };
+2
fs/nfsd/netlink.h
··· 23 23 int nfsd_nl_version_get_doit(struct sk_buff *skb, struct genl_info *info); 24 24 int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info); 25 25 int nfsd_nl_listener_get_doit(struct sk_buff *skb, struct genl_info *info); 26 + int nfsd_nl_pool_mode_set_doit(struct sk_buff *skb, struct genl_info *info); 27 + int nfsd_nl_pool_mode_get_doit(struct sk_buff *skb, struct genl_info *info); 26 28 27 29 extern struct genl_family nfsd_nl_family; 28 30
+57
fs/nfsd/nfsctl.c
··· 2157 2157 } 2158 2158 2159 2159 /** 2160 + * nfsd_nl_pool_mode_set_doit - set the number of running threads 2161 + * @skb: reply buffer 2162 + * @info: netlink metadata and command arguments 2163 + * 2164 + * Return 0 on success or a negative errno. 2165 + */ 2166 + int nfsd_nl_pool_mode_set_doit(struct sk_buff *skb, struct genl_info *info) 2167 + { 2168 + const struct nlattr *attr; 2169 + 2170 + if (GENL_REQ_ATTR_CHECK(info, NFSD_A_POOL_MODE_MODE)) 2171 + return -EINVAL; 2172 + 2173 + attr = info->attrs[NFSD_A_POOL_MODE_MODE]; 2174 + return sunrpc_set_pool_mode(nla_data(attr)); 2175 + } 2176 + 2177 + /** 2178 + * nfsd_nl_pool_mode_get_doit - get info about pool_mode 2179 + * @skb: reply buffer 2180 + * @info: netlink metadata and command arguments 2181 + * 2182 + * Return 0 on success or a negative errno. 2183 + */ 2184 + int nfsd_nl_pool_mode_get_doit(struct sk_buff *skb, struct genl_info *info) 2185 + { 2186 + struct net *net = genl_info_net(info); 2187 + char buf[16]; 2188 + void *hdr; 2189 + int err; 2190 + 2191 + if (sunrpc_get_pool_mode(buf, ARRAY_SIZE(buf)) >= ARRAY_SIZE(buf)) 2192 + return -ERANGE; 2193 + 2194 + skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 2195 + if (!skb) 2196 + return -ENOMEM; 2197 + 2198 + err = -EMSGSIZE; 2199 + hdr = genlmsg_iput(skb, info); 2200 + if (!hdr) 2201 + goto err_free_msg; 2202 + 2203 + err = nla_put_string(skb, NFSD_A_POOL_MODE_MODE, buf) | 2204 + nla_put_u32(skb, NFSD_A_POOL_MODE_NPOOLS, nfsd_nrpools(net)); 2205 + if (err) 2206 + goto err_free_msg; 2207 + 2208 + genlmsg_end(skb, hdr); 2209 + return genlmsg_reply(skb, info); 2210 + 2211 + err_free_msg: 2212 + nlmsg_free(skb); 2213 + return err; 2214 + } 2215 + 2216 + /** 2160 2217 * nfsd_net_init - Prepare the nfsd_net portion of a new net namespace 2161 2218 * @net: a freshly-created network namespace 2162 2219 *
+10
include/uapi/linux/nfsd_netlink.h
··· 71 71 }; 72 72 73 73 enum { 74 + NFSD_A_POOL_MODE_MODE = 1, 75 + NFSD_A_POOL_MODE_NPOOLS, 76 + 77 + __NFSD_A_POOL_MODE_MAX, 78 + NFSD_A_POOL_MODE_MAX = (__NFSD_A_POOL_MODE_MAX - 1) 79 + }; 80 + 81 + enum { 74 82 NFSD_CMD_RPC_STATUS_GET = 1, 75 83 NFSD_CMD_THREADS_SET, 76 84 NFSD_CMD_THREADS_GET, ··· 86 78 NFSD_CMD_VERSION_GET, 87 79 NFSD_CMD_LISTENER_SET, 88 80 NFSD_CMD_LISTENER_GET, 81 + NFSD_CMD_POOL_MODE_SET, 82 + NFSD_CMD_POOL_MODE_GET, 89 83 90 84 __NFSD_CMD_MAX, 91 85 NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)