1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 *
24 * Copyright 2011, 2012 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2013 Joyent, Inc. All rights reserved.
26 */
27
28 /*
29 * This is the loadable module wrapper.
30 */
31 #include <sys/systm.h>
32 #include <sys/modctl.h>
33 #include <sys/syscall.h>
34 #include <sys/ddi.h>
35 #include <sys/cmn_err.h>
36
37 #include <nfs/nfs.h>
38 #include <nfs/nfs_clnt.h>
39 #include <nfs/nfs4.h>
40 #include <nfs/rnode4.h>
41
42 /*
43 * The global tag list.
44 */
45 ctag_t nfs4_ctags[] = NFS4_TAG_INITIALIZER;
46
47 /*
48 * The NFS Version 4 client VFS.
49 */
50 static vfsdef_t vfw4 = {
51 VFSDEF_VERSION,
52 "nfs4",
53 nfs4init,
54 VSW_CANREMOUNT|VSW_NOTZONESAFE|VSW_STATS,
55 NULL
56 };
57
58 struct modlfs modlfs4 = {
59 &mod_fsops,
60 "network filesystem version 4",
61 &vfw4
62 };
63
64 uint_t nfs4_max_transfer_size = 32 * 1024;
65 uint_t nfs4_max_transfer_size_cots = 1024 * 1024;
66 uint_t nfs4_max_transfer_size_rdma = 1024 * 1024;
67
68 int
nfs4tsize(void)69 nfs4tsize(void)
70 {
71 /*
72 * For the moment, just return nfs4_max_transfer_size until we
73 * can query the appropriate transport.
74 */
75 return (nfs4_max_transfer_size);
76 }
77
78 uint_t
nfs4_tsize(struct knetconfig * knp)79 nfs4_tsize(struct knetconfig *knp)
80 {
81
82 if (knp->knc_semantics == NC_TPI_COTS_ORD ||
83 knp->knc_semantics == NC_TPI_COTS)
84 return (nfs4_max_transfer_size_cots);
85 if (knp->knc_semantics == NC_TPI_RDMA)
86 return (nfs4_max_transfer_size_rdma);
87 return (nfs4_max_transfer_size);
88 }
89
90 uint_t
rfs4_tsize(struct svc_req * req)91 rfs4_tsize(struct svc_req *req)
92 {
93
94 if (req->rq_xprt->xp_type == T_COTS_ORD ||
95 req->rq_xprt->xp_type == T_COTS)
96 return (nfs4_max_transfer_size_cots);
97 if (req->rq_xprt->xp_type == T_RDMA)
98 return (nfs4_max_transfer_size_rdma);
99 return (nfs4_max_transfer_size);
100 }
101
102 int
nfs4_setopts(vnode_t * vp,model_t model,struct nfs_args * buf)103 nfs4_setopts(vnode_t *vp, model_t model, struct nfs_args *buf)
104 {
105 mntinfo4_t *mi; /* mount info, pointed at by vfs */
106 STRUCT_HANDLE(nfs_args, args);
107 int flags;
108
109 #ifdef lint
110 model = model;
111 #endif
112
113 STRUCT_SET_HANDLE(args, model, buf);
114
115 flags = STRUCT_FGET(args, flags);
116
117 /*
118 * Set option fields in mount info record
119 */
120 mi = VTOMI4(vp);
121
122
123 if (flags & NFSMNT_NOAC) {
124 mutex_enter(&mi->mi_lock);
125 mi->mi_flags |= MI4_NOAC;
126 mutex_exit(&mi->mi_lock);
127 PURGE_ATTRCACHE4(vp);
128 }
129
130 mutex_enter(&mi->mi_lock);
131 if (flags & NFSMNT_NOCTO)
132 mi->mi_flags |= MI4_NOCTO;
133 if (flags & NFSMNT_LLOCK)
134 mi->mi_flags |= MI4_LLOCK;
135 if (flags & NFSMNT_GRPID)
136 mi->mi_flags |= MI4_GRPID;
137 mutex_exit(&mi->mi_lock);
138
139 if (flags & NFSMNT_RETRANS) {
140 if (STRUCT_FGET(args, retrans) < 0)
141 return (EINVAL);
142 mi->mi_retrans = STRUCT_FGET(args, retrans);
143 }
144 if (flags & NFSMNT_TIMEO) {
145 if (STRUCT_FGET(args, timeo) <= 0)
146 return (EINVAL);
147 mi->mi_timeo = STRUCT_FGET(args, timeo);
148 }
149 if (flags & NFSMNT_RSIZE) {
150 if (STRUCT_FGET(args, rsize) <= 0)
151 return (EINVAL);
152 mi->mi_tsize = MIN(mi->mi_tsize, STRUCT_FGET(args, rsize));
153 mi->mi_curread = MIN(mi->mi_curread, mi->mi_tsize);
154 }
155 if (flags & NFSMNT_WSIZE) {
156 if (STRUCT_FGET(args, wsize) <= 0)
157 return (EINVAL);
158 mi->mi_stsize = MIN(mi->mi_stsize, STRUCT_FGET(args, wsize));
159 mi->mi_curwrite = MIN(mi->mi_curwrite, mi->mi_stsize);
160 }
161 if (flags & NFSMNT_ACREGMIN) {
162 if (STRUCT_FGET(args, acregmin) < 0)
163 mi->mi_acregmin = SEC2HR(ACMINMAX);
164 else
165 mi->mi_acregmin = SEC2HR(MIN(STRUCT_FGET(args,
166 acregmin), ACMINMAX));
167 }
168 if (flags & NFSMNT_ACREGMAX) {
169 if (STRUCT_FGET(args, acregmax) < 0)
170 mi->mi_acregmax = SEC2HR(ACMAXMAX);
171 else
172 mi->mi_acregmax = SEC2HR(MIN(STRUCT_FGET(args,
173 acregmax), ACMAXMAX));
174 }
175 if (flags & NFSMNT_ACDIRMIN) {
176 if (STRUCT_FGET(args, acdirmin) < 0)
177 mi->mi_acdirmin = SEC2HR(ACMINMAX);
178 else
179 mi->mi_acdirmin = SEC2HR(MIN(STRUCT_FGET(args,
180 acdirmin), ACMINMAX));
181 }
182 if (flags & NFSMNT_ACDIRMAX) {
183 if (STRUCT_FGET(args, acdirmax) < 0)
184 mi->mi_acdirmax = SEC2HR(ACMAXMAX);
185 else
186 mi->mi_acdirmax = SEC2HR(MIN(STRUCT_FGET(args,
187 acdirmax), ACMAXMAX));
188 }
189
190 return (0);
191 }
192
193 /*
194 * This returns 1 if the seqid should be bumped upon receiving this
195 * 'res->status' for a seqid dependent operation; otherwise return 0.
196 */
197 int
nfs4_need_to_bump_seqid(COMPOUND4res_clnt * res)198 nfs4_need_to_bump_seqid(COMPOUND4res_clnt *res)
199 {
200 int i, seqid_dep_op = 0;
201 nfs_resop4 *resop;
202
203 resop = res->array;
204
205 for (i = 0; i < res->array_len; i++) {
206 switch (resop[i].resop) {
207 case OP_CLOSE:
208 case OP_OPEN:
209 case OP_OPEN_CONFIRM:
210 case OP_OPEN_DOWNGRADE:
211 case OP_LOCK:
212 case OP_LOCKU:
213 seqid_dep_op = 1;
214 break;
215 default:
216 continue;
217 }
218 }
219
220 if (!seqid_dep_op)
221 return (0);
222
223 switch (res->status) {
224 case NFS4ERR_STALE_CLIENTID:
225 case NFS4ERR_STALE_STATEID:
226 case NFS4ERR_BAD_STATEID:
227 case NFS4ERR_BAD_SEQID:
228 case NFS4ERR_BADXDR:
229 case NFS4ERR_OLD_STATEID:
230 case NFS4ERR_RESOURCE:
231 case NFS4ERR_NOFILEHANDLE:
232 return (0);
233 default:
234 return (1);
235 }
236 }
237
238 /*
239 * Returns 1 if the error is a RPC error that we should retry.
240 */
241 int
nfs4_rpc_retry_error(int error)242 nfs4_rpc_retry_error(int error)
243 {
244 switch (error) {
245 case ETIMEDOUT:
246 case ECONNREFUSED:
247 case ENETDOWN:
248 case ENETUNREACH:
249 case ENETRESET:
250 case ECONNABORTED:
251 case EHOSTUNREACH:
252 case ECONNRESET:
253 return (1);
254 default:
255 return (0);
256 }
257 }
258
259 char *
nfs4_stat_to_str(nfsstat4 error)260 nfs4_stat_to_str(nfsstat4 error)
261 {
262 static char buf[40];
263
264 switch (error) {
265 case NFS4_OK:
266 return ("NFS4_OK");
267 case NFS4ERR_PERM:
268 return ("NFS4ERR_PERM");
269 case NFS4ERR_NOENT:
270 return ("NFS4ERR_NOENT");
271 case NFS4ERR_IO:
272 return ("NFS4ERR_IO");
273 case NFS4ERR_NXIO:
274 return ("NFS4ERR_NXIO");
275 case NFS4ERR_ACCESS:
276 return ("NFS4ERR_ACCESS");
277 case NFS4ERR_EXIST:
278 return ("NFS4ERR_EXIST");
279 case NFS4ERR_XDEV:
280 return ("NFS4ERR_XDEV");
281 case NFS4ERR_NOTDIR:
282 return ("NFS4ERR_NOTDIR");
283 case NFS4ERR_ISDIR:
284 return ("NFS4ERR_ISDIR");
285 case NFS4ERR_INVAL:
286 return ("NFS4ERR_INVAL");
287 case NFS4ERR_FBIG:
288 return ("NFS4ERR_FBIG");
289 case NFS4ERR_NOSPC:
290 return ("NFS4ERR_NOSPC");
291 case NFS4ERR_ROFS:
292 return ("NFS4ERR_ROFS");
293 case NFS4ERR_MLINK:
294 return ("NFS4ERR_MLINK");
295 case NFS4ERR_NAMETOOLONG:
296 return ("NFS4ERR_NAMETOOLONG");
297 case NFS4ERR_NOTEMPTY:
298 return ("NFSS4ERR_NOTEMPTY");
299 case NFS4ERR_DQUOT:
300 return ("NFS4ERR_DQUOT");
301 case NFS4ERR_STALE:
302 return ("NFS4ERR_STALE");
303 case NFS4ERR_BADHANDLE:
304 return ("NFS4ERR_BADHANDLE");
305 case NFS4ERR_BAD_COOKIE:
306 return ("NFS4ERR_BAD_COOKIE");
307 case NFS4ERR_NOTSUPP:
308 return ("NFS4ERR_NOTSUPP");
309 case NFS4ERR_TOOSMALL:
310 return ("NFS4ERR_TOOSMALL");
311 case NFS4ERR_SERVERFAULT:
312 return ("NFS4ERR_SERVERFAULT");
313 case NFS4ERR_BADTYPE:
314 return ("NFS4ERR_BADTYPE");
315 case NFS4ERR_DELAY:
316 return ("NFS4ERR_DELAY");
317 case NFS4ERR_SAME:
318 return ("NFS4ERR_SAME");
319 case NFS4ERR_DENIED:
320 return ("NFS4ERR_DENIED");
321 case NFS4ERR_EXPIRED:
322 return ("NFS4ERR_EXPIRED");
323 case NFS4ERR_LOCKED:
324 return ("NFS4ERR_LOCKED");
325 case NFS4ERR_GRACE:
326 return ("NFS4ERR_GRACE");
327 case NFS4ERR_FHEXPIRED:
328 return ("NFS4ERR_FHEXPIRED");
329 case NFS4ERR_SHARE_DENIED:
330 return ("NFS4ERR_SHARE_DENIED");
331 case NFS4ERR_WRONGSEC:
332 return ("NFS4ERR_WRONGSEC");
333 case NFS4ERR_CLID_INUSE:
334 return ("NFS4ERR_CLID_INUSE");
335 case NFS4ERR_RESOURCE:
336 return ("NFS4ERR_RESOURCE");
337 case NFS4ERR_MOVED:
338 return ("NFS4ERR_MOVED");
339 case NFS4ERR_NOFILEHANDLE:
340 return ("NFS4ERR_NOFILEHANDLE");
341 case NFS4ERR_MINOR_VERS_MISMATCH:
342 return ("NFS4ERR_MINOR_VERS_MISMATCH");
343 case NFS4ERR_STALE_CLIENTID:
344 return ("NFS4ERR_STALE_CLIENTID");
345 case NFS4ERR_STALE_STATEID:
346 return ("NFS4ERR_STALE_STATEID");
347 case NFS4ERR_OLD_STATEID:
348 return ("NFS4ERR_OLD_STATEID");
349 case NFS4ERR_BAD_STATEID:
350 return ("NFS4ERR_BAD_STATEID");
351 case NFS4ERR_BAD_SEQID:
352 return ("NFS4ERR_BAD_SEQID");
353 case NFS4ERR_NOT_SAME:
354 return ("NFS4ERR_NOT_SAME");
355 case NFS4ERR_LOCK_RANGE:
356 return ("NFS4ERR_LOCK_RANGE");
357 case NFS4ERR_SYMLINK:
358 return ("NFS4ERR_SYMLINK");
359 case NFS4ERR_RESTOREFH:
360 return ("NFS4ERR_RESTOREFH");
361 case NFS4ERR_LEASE_MOVED:
362 return ("NFS4ERR_LEASE_MOVED");
363 case NFS4ERR_ATTRNOTSUPP:
364 return ("NFS4ERR_ATTRNOTSUPP");
365 case NFS4ERR_NO_GRACE:
366 return ("NFS4ERR_NO_GRACE");
367 case NFS4ERR_RECLAIM_BAD:
368 return ("NFS4ERR_RECLAIM_BAD");
369 case NFS4ERR_RECLAIM_CONFLICT:
370 return ("NFS4ERR_RECLAIM_CONFLICT");
371 case NFS4ERR_BADXDR:
372 return ("NFS4ERR_BADXDR");
373 case NFS4ERR_LOCKS_HELD:
374 return ("NFS4ERR_LOCKS_HELD");
375 case NFS4ERR_OPENMODE:
376 return ("NFS4ERR_OPENMODE");
377 case NFS4ERR_BADOWNER:
378 return ("NFS4ERR_BADOWNER");
379 case NFS4ERR_BADCHAR:
380 return ("NFS4ERR_BADCHAR");
381 case NFS4ERR_BADNAME:
382 return ("NFS4ERR_BADNAME");
383 case NFS4ERR_BAD_RANGE:
384 return ("NFS4ERR_BAD_RANGE");
385 case NFS4ERR_LOCK_NOTSUPP:
386 return ("NFS4ERR_LOCK_NOTSUPP");
387 case NFS4ERR_OP_ILLEGAL:
388 return ("NFS4ERR_OP_ILLEGAL");
389 case NFS4ERR_DEADLOCK:
390 return ("NFS4ERR_DEADLOCK");
391 case NFS4ERR_FILE_OPEN:
392 return ("NFS4ERR_FILE_OPEN");
393 case NFS4ERR_ADMIN_REVOKED:
394 return ("NFS4ERR_ADMIN_REVOKED");
395 case NFS4ERR_CB_PATH_DOWN:
396 return ("NFS4ERR_CB_PATH_DOWN");
397 default:
398 (void) snprintf(buf, 40, "Unknown error %d", (int)error);
399 return (buf);
400 }
401 }
402
403 char *
nfs4_recov_action_to_str(nfs4_recov_t what)404 nfs4_recov_action_to_str(nfs4_recov_t what)
405 {
406 static char buf[40];
407
408 switch (what) {
409 case NR_STALE:
410 return ("NR_STALE");
411 case NR_FAILOVER:
412 return ("NR_FAILOVER");
413 case NR_CLIENTID:
414 return ("NR_CLIENTID");
415 case NR_OPENFILES:
416 return ("NR_OPENFILES");
417 case NR_WRONGSEC:
418 return ("NR_WRONGSEC");
419 case NR_EXPIRED:
420 return ("NR_EXPIRED");
421 case NR_BAD_STATEID:
422 return ("NR_BAD_STATEID");
423 case NR_FHEXPIRED:
424 return ("NR_FHEXPIRED");
425 case NR_BADHANDLE:
426 return ("NR_BADHANDLE");
427 case NR_BAD_SEQID:
428 return ("NR_BAD_SEQID");
429 case NR_OLDSTATEID:
430 return ("NR_OLDSTATEID");
431 case NR_GRACE:
432 return ("NR_GRACE");
433 case NR_DELAY:
434 return ("NR_DELAY");
435 case NR_LOST_LOCK:
436 return ("NR_LOST_LOCK");
437 case NR_LOST_STATE_RQST:
438 return ("NR_LOST_STATE_RQST");
439 case NR_MOVED:
440 return ("NR_MOVED");
441 default:
442 (void) snprintf(buf, 40, "Unknown, code %d", (int)what);
443 return (buf);
444 }
445 }
446
447 char *
nfs4_op_to_str(nfs_opnum4 op)448 nfs4_op_to_str(nfs_opnum4 op)
449 {
450 static char buf[40];
451
452 switch (REAL_OP4(op)) {
453 case OP_ACCESS:
454 return ("OP_ACCESS");
455 case OP_CLOSE:
456 return ("OP_CLOSE");
457 case OP_COMMIT:
458 return ("OP_COMMIT");
459 case OP_CREATE:
460 return ("OP_CREATE");
461 case OP_DELEGPURGE:
462 return ("OP_DELEGPURGE");
463 case OP_DELEGRETURN:
464 return ("OP_DELEGRETURN");
465 case OP_GETATTR:
466 return ("OP_GETATTR");
467 case OP_GETFH:
468 return ("OP_GETFH");
469 case OP_LINK:
470 return ("OP_LINK");
471 case OP_LOCK:
472 return ("OP_LOCK");
473 case OP_LOCKT:
474 return ("OP_LOCKT");
475 case OP_LOCKU:
476 return ("OP_LOCKU");
477 case OP_LOOKUP:
478 return ("OP_LOOKUP");
479 case OP_LOOKUPP:
480 return ("OP_LOOKUPP");
481 case OP_NVERIFY:
482 return ("OP_NVERIFY");
483 case OP_OPEN:
484 return ("OP_OPEN");
485 case OP_OPENATTR:
486 return ("OP_OPENATTR");
487 case OP_OPEN_CONFIRM:
488 return ("OP_OPEN_CONFIRM");
489 case OP_OPEN_DOWNGRADE:
490 return ("OP_OPEN_DOWNGRADE");
491 case OP_PUTFH:
492 return ("OP_PUTFH");
493 case OP_PUTPUBFH:
494 return ("OP_PUTPUBFH");
495 case OP_PUTROOTFH:
496 return ("OP_PUTROOTFH");
497 case OP_READ:
498 return ("OP_READ");
499 case OP_READDIR:
500 return ("OP_READDIR");
501 case OP_READLINK:
502 return ("OP_READLINK");
503 case OP_REMOVE:
504 return ("OP_REMOVE");
505 case OP_RENAME:
506 return ("OP_RENAME");
507 case OP_RENEW:
508 return ("OP_RENEW");
509 case OP_RESTOREFH:
510 return ("OP_RESTOREFH");
511 case OP_SAVEFH:
512 return ("OP_SAVEFH");
513 case OP_SECINFO:
514 return ("OP_SECINFO");
515 case OP_SETATTR:
516 return ("OP_SETATTR");
517 case OP_SETCLIENTID:
518 return ("OP_SETCLIENTID");
519 case OP_SETCLIENTID_CONFIRM:
520 return ("OP_SETCLIENTID_CONFIRM");
521 case OP_VERIFY:
522 return ("OP_VERIFY");
523 case OP_WRITE:
524 return ("OP_WRITE");
525 case OP_RELEASE_LOCKOWNER:
526 return ("OP_RELEASE_LOCKOWNER");
527 case OP_ILLEGAL:
528 return ("OP_ILLEGAL");
529 default:
530 (void) snprintf(buf, 40, "Unknown op %d", (int)op);
531 return (buf);
532 }
533 }
534