sunrpc: refactor pool_mode setting code

Allow the pool_mode setting code to be called from internal callers
so we can call it from a new netlink op. Add a new svc_pool_map_get
function to return the current setting. Change the existing module
parameter handling to use the new interfaces under the hood.

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 5f71f3c3 7f5c330b

+66 -21
+2
include/linux/sunrpc/svc.h
··· 399 /* 400 * Function prototypes. 401 */ 402 int svc_rpcb_setup(struct svc_serv *serv, struct net *net); 403 void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net); 404 int svc_bind(struct svc_serv *serv, struct net *net);
··· 399 /* 400 * Function prototypes. 401 */ 402 + int sunrpc_set_pool_mode(const char *val); 403 + int sunrpc_get_pool_mode(char *val, size_t size); 404 int svc_rpcb_setup(struct svc_serv *serv, struct net *net); 405 void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net); 406 int svc_bind(struct svc_serv *serv, struct net *net);
+64 -21
net/sunrpc/svc.c
··· 72 static DEFINE_MUTEX(svc_pool_map_mutex);/* protects svc_pool_map.count only */ 73 74 static int 75 - param_set_pool_mode(const char *val, const struct kernel_param *kp) 76 { 77 - int *ip = (int *)kp->arg; 78 - struct svc_pool_map *m = &svc_pool_map; 79 - int err; 80 81 mutex_lock(&svc_pool_map_mutex); 82 83 - err = -EBUSY; 84 - if (m->count) 85 - goto out; 86 - 87 err = 0; 88 if (!strncmp(val, "auto", 4)) 89 - *ip = SVC_POOL_AUTO; 90 else if (!strncmp(val, "global", 6)) 91 - *ip = SVC_POOL_GLOBAL; 92 else if (!strncmp(val, "percpu", 6)) 93 - *ip = SVC_POOL_PERCPU; 94 else if (!strncmp(val, "pernode", 7)) 95 - *ip = SVC_POOL_PERNODE; 96 else 97 err = -EINVAL; 98 99 out: 100 mutex_unlock(&svc_pool_map_mutex); 101 return err; 102 } 103 104 static int 105 - param_get_pool_mode(char *buf, const struct kernel_param *kp) 106 { 107 - int *ip = (int *)kp->arg; 108 109 - switch (*ip) 110 { 111 case SVC_POOL_AUTO: 112 - return sysfs_emit(buf, "auto\n"); 113 case SVC_POOL_GLOBAL: 114 - return sysfs_emit(buf, "global\n"); 115 case SVC_POOL_PERCPU: 116 - return sysfs_emit(buf, "percpu\n"); 117 case SVC_POOL_PERNODE: 118 - return sysfs_emit(buf, "pernode\n"); 119 default: 120 - return sysfs_emit(buf, "%d\n", *ip); 121 } 122 } 123 124 module_param_call(pool_mode, param_set_pool_mode, param_get_pool_mode, 125 - &svc_pool_map.mode, 0644); 126 127 /* 128 * Detect best pool mapping mode heuristically,
··· 72 static DEFINE_MUTEX(svc_pool_map_mutex);/* protects svc_pool_map.count only */ 73 74 static int 75 + __param_set_pool_mode(const char *val, struct svc_pool_map *m) 76 { 77 + int err, mode; 78 79 mutex_lock(&svc_pool_map_mutex); 80 81 err = 0; 82 if (!strncmp(val, "auto", 4)) 83 + mode = SVC_POOL_AUTO; 84 else if (!strncmp(val, "global", 6)) 85 + mode = SVC_POOL_GLOBAL; 86 else if (!strncmp(val, "percpu", 6)) 87 + mode = SVC_POOL_PERCPU; 88 else if (!strncmp(val, "pernode", 7)) 89 + mode = SVC_POOL_PERNODE; 90 else 91 err = -EINVAL; 92 93 + if (err) 94 + goto out; 95 + 96 + if (m->count == 0) 97 + m->mode = mode; 98 + else if (mode != m->mode) 99 + err = -EBUSY; 100 out: 101 mutex_unlock(&svc_pool_map_mutex); 102 return err; 103 } 104 105 static int 106 + param_set_pool_mode(const char *val, const struct kernel_param *kp) 107 { 108 + struct svc_pool_map *m = kp->arg; 109 110 + return __param_set_pool_mode(val, m); 111 + } 112 + 113 + int sunrpc_set_pool_mode(const char *val) 114 + { 115 + return __param_set_pool_mode(val, &svc_pool_map); 116 + } 117 + EXPORT_SYMBOL(sunrpc_set_pool_mode); 118 + 119 + /** 120 + * sunrpc_get_pool_mode - get the current pool_mode for the host 121 + * @buf: where to write the current pool_mode 122 + * @size: size of @buf 123 + * 124 + * Grab the current pool_mode from the svc_pool_map and write 125 + * the resulting string to @buf. Returns the number of characters 126 + * written to @buf (a'la snprintf()). 127 + */ 128 + int 129 + sunrpc_get_pool_mode(char *buf, size_t size) 130 + { 131 + struct svc_pool_map *m = &svc_pool_map; 132 + 133 + switch (m->mode) 134 { 135 case SVC_POOL_AUTO: 136 + return snprintf(buf, size, "auto"); 137 case SVC_POOL_GLOBAL: 138 + return snprintf(buf, size, "global"); 139 case SVC_POOL_PERCPU: 140 + return snprintf(buf, size, "percpu"); 141 case SVC_POOL_PERNODE: 142 + return snprintf(buf, size, "pernode"); 143 default: 144 + return snprintf(buf, size, "%d", m->mode); 145 } 146 + } 147 + EXPORT_SYMBOL(sunrpc_get_pool_mode); 148 + 149 + static int 150 + param_get_pool_mode(char *buf, const struct kernel_param *kp) 151 + { 152 + char str[16]; 153 + int len; 154 + 155 + len = sunrpc_get_pool_mode(str, ARRAY_SIZE(str)); 156 + 157 + /* Ensure we have room for newline and NUL */ 158 + len = min_t(int, len, ARRAY_SIZE(str) - 2); 159 + 160 + /* tack on the newline */ 161 + str[len] = '\n'; 162 + str[len + 1] = '\0'; 163 + 164 + return sysfs_emit(buf, str); 165 } 166 167 module_param_call(pool_mode, param_set_pool_mode, param_get_pool_mode, 168 + &svc_pool_map, 0644); 169 170 /* 171 * Detect best pool mapping mode heuristically,