Print this page
5253 kmem_alloc/kmem_zalloc won't fail with KM_SLEEP
5254 getrbuf won't fail with KM_SLEEP
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/nfs/nfs_sys.c
+++ new/usr/src/uts/common/fs/nfs/nfs_sys.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 *
25 25 * Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
26 26 * All rights reserved.
27 27 */
28 28
29 29 #include <sys/types.h>
30 30 #include <rpc/types.h>
31 31 #include <sys/systm.h>
32 32 #include <sys/vfs.h>
33 33 #include <sys/errno.h>
34 34 #include <sys/cred.h>
35 35 #include <sys/policy.h>
36 36 #include <sys/siginfo.h>
37 37 #include <sys/proc.h> /* for exit() declaration */
38 38 #include <sys/kmem.h>
39 39 #include <nfs/nfs4.h>
40 40 #include <nfs/nfssys.h>
41 41 #include <sys/thread.h>
42 42 #include <rpc/auth.h>
43 43 #include <rpc/rpcsys.h>
44 44 #include <rpc/svc.h>
45 45
46 46 /*
47 47 * This is filled in with an appropriate address for the
48 48 * function that will traverse the rfs4_client_t table
49 49 * and mark any matching IP Address as "forced_expire".
50 50 *
51 51 * It is the server init() function that plops the
52 52 * function pointer.
53 53 */
54 54 void (*rfs4_client_clrst)(struct nfs4clrst_args *) = NULL;
55 55
56 56 /* This filled in by nfssrv:_init() */
57 57 void (*nfs_srv_quiesce_func)(void) = NULL;
58 58
59 59 extern void nfscmd_args(uint_t);
60 60
61 61 /*
62 62 * These will be reset by klmmod:lm_svc(), when lockd starts NLM service,
63 63 * based on values read by lockd from /etc/default/nfs. Since nfssrv depends on
64 64 * klmmod, the declarations need to be here (in nfs, on which both depend) so
65 65 * that nfssrv can see the klmmod changes.
66 66 * When the dependency of NFSv4 on NLM/lockd is removed, this will need to
67 67 * be adjusted.
68 68 */
69 69 #define RFS4_LEASETIME 90 /* seconds */
70 70 time_t rfs4_lease_time = RFS4_LEASETIME;
71 71 time_t rfs4_grace_period = RFS4_LEASETIME;
72 72
73 73 /* DSS: distributed stable storage */
74 74 size_t nfs4_dss_buflen = 0;
75 75 /* This filled in by nfssrv:_init() */
76 76 int (*nfs_srv_dss_func)(char *, size_t) = NULL;
77 77
78 78 int
79 79 nfs_export(void *arg)
80 80 {
81 81 STRUCT_DECL(exportfs_args, ea);
82 82
83 83 if (!INGLOBALZONE(curproc))
84 84 return (set_errno(EPERM));
85 85 STRUCT_INIT(ea, get_udatamodel());
86 86 if (copyin(arg, STRUCT_BUF(ea), STRUCT_SIZE(ea)))
87 87 return (set_errno(EFAULT));
88 88
89 89 return (exportfs(STRUCT_BUF(ea), get_udatamodel(), CRED()));
90 90 }
91 91
92 92 int
93 93 nfssys(enum nfssys_op opcode, void *arg)
94 94 {
95 95 int error = 0;
96 96
97 97 if (!(opcode == NFS_REVAUTH || opcode == NFS4_SVC) &&
98 98 secpolicy_nfs(CRED()) != 0)
99 99 return (set_errno(EPERM));
100 100
101 101 switch (opcode) {
102 102 case NFS4_CLR_STATE: { /* Clear NFS4 client state */
103 103 struct nfs4clrst_args clr;
104 104 STRUCT_DECL(nfs4clrst_args, u_clr);
105 105
106 106 /*
107 107 * If the server is not loaded then no point in
108 108 * clearing nothing :-)
109 109 */
110 110 if (rfs4_client_clrst == NULL) {
111 111 break;
112 112 }
113 113
114 114 if (!INGLOBALZONE(curproc))
115 115 return (set_errno(EPERM));
116 116
117 117 STRUCT_INIT(u_clr, get_udatamodel());
118 118
119 119 if (copyin(arg, STRUCT_BUF(u_clr), STRUCT_SIZE(u_clr)))
120 120 return (set_errno(EFAULT));
121 121
122 122 clr.vers = STRUCT_FGET(u_clr, vers);
123 123
124 124 if (clr.vers != NFS4_CLRST_VERSION)
125 125 return (set_errno(EINVAL));
126 126
127 127 clr.addr_type = STRUCT_FGET(u_clr, addr_type);
128 128 clr.ap = STRUCT_FGETP(u_clr, ap);
129 129 rfs4_client_clrst(&clr);
130 130 break;
131 131 }
132 132
133 133 case SVCPOOL_CREATE: { /* setup an RPC server thread pool */
134 134 struct svcpool_args p;
135 135
136 136 if (copyin(arg, &p, sizeof (p)))
137 137 return (set_errno(EFAULT));
138 138
139 139 error = svc_pool_create(&p);
140 140 break;
141 141 }
142 142
143 143 case SVCPOOL_WAIT: { /* wait in kernel for threads to be needed */
144 144 int id;
145 145
146 146 if (copyin(arg, &id, sizeof (id)))
147 147 return (set_errno(EFAULT));
148 148
149 149 error = svc_wait(id);
150 150 break;
151 151 }
152 152
153 153 case SVCPOOL_RUN: { /* give work to a runnable thread */
154 154 int id;
155 155
156 156 if (copyin(arg, &id, sizeof (id)))
157 157 return (set_errno(EFAULT));
158 158
159 159 error = svc_do_run(id);
160 160 break;
161 161 }
162 162
163 163 case RDMA_SVC_INIT: {
164 164 struct rdma_svc_args rsa;
165 165 char netstore[20] = "tcp";
166 166
167 167 if (!INGLOBALZONE(curproc))
168 168 return (set_errno(EPERM));
169 169 if (get_udatamodel() != DATAMODEL_NATIVE) {
170 170 STRUCT_DECL(rdma_svc_args, ursa);
171 171
172 172 STRUCT_INIT(ursa, get_udatamodel());
173 173 if (copyin(arg, STRUCT_BUF(ursa), STRUCT_SIZE(ursa)))
174 174 return (set_errno(EFAULT));
175 175
176 176 rsa.poolid = STRUCT_FGET(ursa, poolid);
177 177 rsa.nfs_versmin = STRUCT_FGET(ursa, nfs_versmin);
178 178 rsa.nfs_versmax = STRUCT_FGET(ursa, nfs_versmax);
179 179 rsa.delegation = STRUCT_FGET(ursa, delegation);
180 180 } else {
181 181 if (copyin(arg, &rsa, sizeof (rsa)))
182 182 return (set_errno(EFAULT));
183 183 }
184 184 rsa.netid = netstore;
185 185
186 186 error = rdma_start(&rsa);
187 187 break;
188 188 }
189 189
190 190 case NFS_SVC: { /* NFS server daemon */
191 191 STRUCT_DECL(nfs_svc_args, nsa);
192 192
193 193 if (!INGLOBALZONE(curproc))
194 194 return (set_errno(EPERM));
195 195 STRUCT_INIT(nsa, get_udatamodel());
196 196
197 197 if (copyin(arg, STRUCT_BUF(nsa), STRUCT_SIZE(nsa)))
198 198 return (set_errno(EFAULT));
199 199
200 200 error = nfs_svc(STRUCT_BUF(nsa), get_udatamodel());
201 201 break;
202 202 }
203 203
204 204 case EXPORTFS: { /* export a file system */
205 205 error = nfs_export(arg);
206 206 break;
207 207 }
208 208
209 209 case NFS_GETFH: { /* get a file handle */
210 210 STRUCT_DECL(nfs_getfh_args, nga);
211 211
212 212 if (!INGLOBALZONE(curproc))
213 213 return (set_errno(EPERM));
214 214 STRUCT_INIT(nga, get_udatamodel());
215 215 if (copyin(arg, STRUCT_BUF(nga), STRUCT_SIZE(nga)))
216 216 return (set_errno(EFAULT));
217 217
218 218 error = nfs_getfh(STRUCT_BUF(nga), get_udatamodel(), CRED());
219 219 break;
220 220 }
221 221
222 222 case NFS_REVAUTH: { /* revoke the cached credentials for the uid */
223 223 STRUCT_DECL(nfs_revauth_args, nra);
224 224
225 225 STRUCT_INIT(nra, get_udatamodel());
226 226 if (copyin(arg, STRUCT_BUF(nra), STRUCT_SIZE(nra)))
227 227 return (set_errno(EFAULT));
228 228
229 229 /* This call performs its own privilege checking */
230 230 error = sec_clnt_revoke(STRUCT_FGET(nra, authtype),
231 231 STRUCT_FGET(nra, uid), CRED(), NULL, get_udatamodel());
232 232 break;
233 233 }
234 234
235 235 case LM_SVC: { /* LM server daemon */
236 236 struct lm_svc_args lsa;
237 237
238 238 if (get_udatamodel() != DATAMODEL_NATIVE) {
239 239 STRUCT_DECL(lm_svc_args, ulsa);
240 240
241 241 STRUCT_INIT(ulsa, get_udatamodel());
242 242 if (copyin(arg, STRUCT_BUF(ulsa), STRUCT_SIZE(ulsa)))
243 243 return (set_errno(EFAULT));
244 244
245 245 lsa.version = STRUCT_FGET(ulsa, version);
246 246 lsa.fd = STRUCT_FGET(ulsa, fd);
247 247 lsa.n_fmly = STRUCT_FGET(ulsa, n_fmly);
248 248 lsa.n_proto = STRUCT_FGET(ulsa, n_proto);
249 249 lsa.n_rdev = expldev(STRUCT_FGET(ulsa, n_rdev));
250 250 lsa.debug = STRUCT_FGET(ulsa, debug);
251 251 lsa.timout = STRUCT_FGET(ulsa, timout);
252 252 lsa.grace = STRUCT_FGET(ulsa, grace);
253 253 lsa.retransmittimeout = STRUCT_FGET(ulsa,
254 254 retransmittimeout);
255 255 } else {
256 256 if (copyin(arg, &lsa, sizeof (lsa)))
257 257 return (set_errno(EFAULT));
258 258 }
259 259
260 260 error = lm_svc(&lsa);
261 261 break;
262 262 }
263 263
264 264 case KILL_LOCKMGR: {
265 265 error = lm_shutdown();
266 266 break;
267 267 }
268 268
269 269 case LOG_FLUSH: { /* Flush log buffer and possibly rename */
270 270 STRUCT_DECL(nfsl_flush_args, nfa);
271 271
272 272 STRUCT_INIT(nfa, get_udatamodel());
273 273 if (copyin(arg, STRUCT_BUF(nfa), STRUCT_SIZE(nfa)))
274 274 return (set_errno(EFAULT));
275 275
276 276 error = nfsl_flush(STRUCT_BUF(nfa), get_udatamodel());
277 277 break;
278 278 }
279 279
280 280 case NFS4_SVC: { /* NFS client callback daemon */
281 281
282 282 STRUCT_DECL(nfs4_svc_args, nsa);
283 283
284 284 STRUCT_INIT(nsa, get_udatamodel());
285 285
286 286 if (copyin(arg, STRUCT_BUF(nsa), STRUCT_SIZE(nsa)))
287 287 return (set_errno(EFAULT));
288 288
289 289 error = nfs4_svc(STRUCT_BUF(nsa), get_udatamodel());
290 290 break;
291 291 }
292 292
293 293 /* Request that NFSv4 server quiesce on next shutdown */
294 294 case NFS4_SVC_REQUEST_QUIESCE: {
295 295 int id;
296 296
297 297 /* check that nfssrv module is loaded */
298 298 if (nfs_srv_quiesce_func == NULL)
299 299 return (set_errno(ENOTSUP));
300 300
301 301 if (copyin(arg, &id, sizeof (id)))
302 302 return (set_errno(EFAULT));
303 303
304 304 error = svc_pool_control(id, SVCPSET_SHUTDOWN_PROC,
305 305 (void *)nfs_srv_quiesce_func);
306 306 break;
307 307 }
308 308
309 309 case NFS_IDMAP: {
310 310 struct nfsidmap_args idm;
311 311
312 312 if (copyin(arg, &idm, sizeof (idm)))
313 313 return (set_errno(EFAULT));
314 314
315 315 nfs_idmap_args(&idm);
316 316 error = 0;
317 317 break;
318 318 }
319 319
320 320 case NFS4_DSS_SETPATHS_SIZE: {
321 321 /* crosses ILP32/LP64 boundary */
322 322 uint32_t nfs4_dss_bufsize = 0;
323 323
324 324 if (copyin(arg, &nfs4_dss_bufsize, sizeof (nfs4_dss_bufsize)))
325 325 return (set_errno(EFAULT));
326 326 nfs4_dss_buflen = (long)nfs4_dss_bufsize;
327 327 error = 0;
328 328 break;
329 329 }
330 330
331 331 case NFS4_DSS_SETPATHS: {
332 332 char *nfs4_dss_bufp;
333 333
334 334 /* check that nfssrv module is loaded */
335 335 if (nfs_srv_dss_func == NULL)
↓ open down ↓ |
335 lines elided |
↑ open up ↑ |
336 336 return (set_errno(ENOTSUP));
337 337
338 338 /*
339 339 * NFS4_DSS_SETPATHS_SIZE must be called before
340 340 * NFS4_DSS_SETPATHS, to tell us how big a buffer we need
341 341 * to allocate.
342 342 */
343 343 if (nfs4_dss_buflen == 0)
344 344 return (set_errno(EINVAL));
345 345 nfs4_dss_bufp = kmem_alloc(nfs4_dss_buflen, KM_SLEEP);
346 - if (nfs4_dss_bufp == NULL)
347 - return (set_errno(ENOMEM));
348 346
349 347 if (copyin(arg, nfs4_dss_bufp, nfs4_dss_buflen)) {
350 348 kmem_free(nfs4_dss_bufp, nfs4_dss_buflen);
351 349 return (set_errno(EFAULT));
352 350 }
353 351
354 352 /* unpack the buffer and extract the pathnames */
355 353 error = nfs_srv_dss_func(nfs4_dss_bufp, nfs4_dss_buflen);
356 354 kmem_free(nfs4_dss_bufp, nfs4_dss_buflen);
357 355
358 356 break;
359 357 }
360 358
361 359 case NFS4_EPHEMERAL_MOUNT_TO: {
362 360 uint_t mount_to;
363 361
364 362 /*
365 363 * Not a very complicated call.
366 364 */
367 365 if (copyin(arg, &mount_to, sizeof (mount_to)))
368 366 return (set_errno(EFAULT));
369 367 nfs4_ephemeral_set_mount_to(mount_to);
370 368 error = 0;
371 369 break;
372 370 }
373 371
374 372 case MOUNTD_ARGS: {
375 373 uint_t did;
376 374
377 375 /*
378 376 * For now, only passing down the door fd; if we
379 377 * ever need to pass down more info, we can use
380 378 * a (properly aligned) struct.
381 379 */
382 380 if (copyin(arg, &did, sizeof (did)))
383 381 return (set_errno(EFAULT));
384 382 mountd_args(did);
385 383 error = 0;
386 384 break;
387 385 }
388 386
389 387 case NFSCMD_ARGS: {
390 388 uint_t did;
391 389
392 390 /*
393 391 * For now, only passing down the door fd; if we
394 392 * ever need to pass down more info, we can use
395 393 * a (properly aligned) struct.
396 394 */
397 395 if (copyin(arg, &did, sizeof (did)))
398 396 return (set_errno(EFAULT));
399 397 nfscmd_args(did);
400 398 error = 0;
401 399 break;
402 400 }
403 401
404 402 default:
405 403 error = EINVAL;
406 404 break;
407 405 }
408 406
409 407 return ((error != 0) ? set_errno(error) : 0);
410 408 }
↓ open down ↓ |
53 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX