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.
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.
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]
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2011, 2012 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2013 Joyent, Inc. All rights reserved.
29 * This is the loadable module wrapper.
31 #include <sys/systm.h>
32 #include <sys/modctl.h>
33 #include <sys/syscall.h>
35 #include <sys/cmn_err.h>
38 #include <nfs/nfs_clnt.h>
40 #include <nfs/rnode4.h>
43 * The global tag list.
45 ctag_t nfs4_ctags
[] = NFS4_TAG_INITIALIZER
;
48 * The NFS Version 4 client VFS.
50 static vfsdef_t vfw4
= {
54 VSW_CANREMOUNT
|VSW_NOTZONESAFE
|VSW_STATS
,
58 struct modlfs modlfs4
= {
60 "network filesystem version 4",
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;
72 * For the moment, just return nfs4_max_transfer_size until we
73 * can query the appropriate transport.
75 return (nfs4_max_transfer_size
);
79 nfs4_tsize(struct knetconfig
*knp
)
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
);
91 rfs4_tsize(struct svc_req
*req
)
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
);
103 nfs4_setopts(vnode_t
*vp
, model_t model
, struct nfs_args
*buf
)
105 mntinfo4_t
*mi
; /* mount info, pointed at by vfs */
106 STRUCT_HANDLE(nfs_args
, args
);
110 STRUCT_SET_HANDLE(args
, model
, buf
);
112 flags
= STRUCT_FGET(args
, flags
);
115 * Set option fields in mount info record
120 if (flags
& NFSMNT_NOAC
) {
121 mutex_enter(&mi
->mi_lock
);
122 mi
->mi_flags
|= MI4_NOAC
;
123 mutex_exit(&mi
->mi_lock
);
124 PURGE_ATTRCACHE4(vp
);
127 mutex_enter(&mi
->mi_lock
);
128 if (flags
& NFSMNT_NOCTO
)
129 mi
->mi_flags
|= MI4_NOCTO
;
130 if (flags
& NFSMNT_LLOCK
)
131 mi
->mi_flags
|= MI4_LLOCK
;
132 if (flags
& NFSMNT_GRPID
)
133 mi
->mi_flags
|= MI4_GRPID
;
134 mutex_exit(&mi
->mi_lock
);
136 if (flags
& NFSMNT_RETRANS
) {
137 if (STRUCT_FGET(args
, retrans
) < 0)
139 mi
->mi_retrans
= STRUCT_FGET(args
, retrans
);
141 if (flags
& NFSMNT_TIMEO
) {
142 if (STRUCT_FGET(args
, timeo
) <= 0)
144 mi
->mi_timeo
= STRUCT_FGET(args
, timeo
);
146 if (flags
& NFSMNT_RSIZE
) {
147 if (STRUCT_FGET(args
, rsize
) <= 0)
149 mi
->mi_tsize
= MIN(mi
->mi_tsize
, STRUCT_FGET(args
, rsize
));
150 mi
->mi_curread
= MIN(mi
->mi_curread
, mi
->mi_tsize
);
152 if (flags
& NFSMNT_WSIZE
) {
153 if (STRUCT_FGET(args
, wsize
) <= 0)
155 mi
->mi_stsize
= MIN(mi
->mi_stsize
, STRUCT_FGET(args
, wsize
));
156 mi
->mi_curwrite
= MIN(mi
->mi_curwrite
, mi
->mi_stsize
);
158 if (flags
& NFSMNT_ACREGMIN
) {
159 if (STRUCT_FGET(args
, acregmin
) < 0)
160 mi
->mi_acregmin
= SEC2HR(ACMINMAX
);
162 mi
->mi_acregmin
= SEC2HR(MIN(STRUCT_FGET(args
,
163 acregmin
), ACMINMAX
));
165 if (flags
& NFSMNT_ACREGMAX
) {
166 if (STRUCT_FGET(args
, acregmax
) < 0)
167 mi
->mi_acregmax
= SEC2HR(ACMAXMAX
);
169 mi
->mi_acregmax
= SEC2HR(MIN(STRUCT_FGET(args
,
170 acregmax
), ACMAXMAX
));
172 if (flags
& NFSMNT_ACDIRMIN
) {
173 if (STRUCT_FGET(args
, acdirmin
) < 0)
174 mi
->mi_acdirmin
= SEC2HR(ACMINMAX
);
176 mi
->mi_acdirmin
= SEC2HR(MIN(STRUCT_FGET(args
,
177 acdirmin
), ACMINMAX
));
179 if (flags
& NFSMNT_ACDIRMAX
) {
180 if (STRUCT_FGET(args
, acdirmax
) < 0)
181 mi
->mi_acdirmax
= SEC2HR(ACMAXMAX
);
183 mi
->mi_acdirmax
= SEC2HR(MIN(STRUCT_FGET(args
,
184 acdirmax
), ACMAXMAX
));
191 * This returns 1 if the seqid should be bumped upon receiving this
192 * 'res->status' for a seqid dependent operation; otherwise return 0.
195 nfs4_need_to_bump_seqid(COMPOUND4res_clnt
*res
)
197 int i
, seqid_dep_op
= 0;
202 for (i
= 0; i
< res
->array_len
; i
++) {
203 switch (resop
[i
].resop
) {
206 case OP_OPEN_CONFIRM
:
207 case OP_OPEN_DOWNGRADE
:
220 switch (res
->status
) {
221 case NFS4ERR_STALE_CLIENTID
:
222 case NFS4ERR_STALE_STATEID
:
223 case NFS4ERR_BAD_STATEID
:
224 case NFS4ERR_BAD_SEQID
:
226 case NFS4ERR_OLD_STATEID
:
227 case NFS4ERR_RESOURCE
:
228 case NFS4ERR_NOFILEHANDLE
:
236 * Returns 1 if the error is a RPC error that we should retry.
239 nfs4_rpc_retry_error(int error
)
257 nfs4_stat_to_str(nfsstat4 error
)
265 return ("NFS4ERR_PERM");
267 return ("NFS4ERR_NOENT");
269 return ("NFS4ERR_IO");
271 return ("NFS4ERR_NXIO");
273 return ("NFS4ERR_ACCESS");
275 return ("NFS4ERR_EXIST");
277 return ("NFS4ERR_XDEV");
279 return ("NFS4ERR_NOTDIR");
281 return ("NFS4ERR_ISDIR");
283 return ("NFS4ERR_INVAL");
285 return ("NFS4ERR_FBIG");
287 return ("NFS4ERR_NOSPC");
289 return ("NFS4ERR_ROFS");
291 return ("NFS4ERR_MLINK");
292 case NFS4ERR_NAMETOOLONG
:
293 return ("NFS4ERR_NAMETOOLONG");
294 case NFS4ERR_NOTEMPTY
:
295 return ("NFSS4ERR_NOTEMPTY");
297 return ("NFS4ERR_DQUOT");
299 return ("NFS4ERR_STALE");
300 case NFS4ERR_BADHANDLE
:
301 return ("NFS4ERR_BADHANDLE");
302 case NFS4ERR_BAD_COOKIE
:
303 return ("NFS4ERR_BAD_COOKIE");
304 case NFS4ERR_NOTSUPP
:
305 return ("NFS4ERR_NOTSUPP");
306 case NFS4ERR_TOOSMALL
:
307 return ("NFS4ERR_TOOSMALL");
308 case NFS4ERR_SERVERFAULT
:
309 return ("NFS4ERR_SERVERFAULT");
310 case NFS4ERR_BADTYPE
:
311 return ("NFS4ERR_BADTYPE");
313 return ("NFS4ERR_DELAY");
315 return ("NFS4ERR_SAME");
317 return ("NFS4ERR_DENIED");
318 case NFS4ERR_EXPIRED
:
319 return ("NFS4ERR_EXPIRED");
321 return ("NFS4ERR_LOCKED");
323 return ("NFS4ERR_GRACE");
324 case NFS4ERR_FHEXPIRED
:
325 return ("NFS4ERR_FHEXPIRED");
326 case NFS4ERR_SHARE_DENIED
:
327 return ("NFS4ERR_SHARE_DENIED");
328 case NFS4ERR_WRONGSEC
:
329 return ("NFS4ERR_WRONGSEC");
330 case NFS4ERR_CLID_INUSE
:
331 return ("NFS4ERR_CLID_INUSE");
332 case NFS4ERR_RESOURCE
:
333 return ("NFS4ERR_RESOURCE");
335 return ("NFS4ERR_MOVED");
336 case NFS4ERR_NOFILEHANDLE
:
337 return ("NFS4ERR_NOFILEHANDLE");
338 case NFS4ERR_MINOR_VERS_MISMATCH
:
339 return ("NFS4ERR_MINOR_VERS_MISMATCH");
340 case NFS4ERR_STALE_CLIENTID
:
341 return ("NFS4ERR_STALE_CLIENTID");
342 case NFS4ERR_STALE_STATEID
:
343 return ("NFS4ERR_STALE_STATEID");
344 case NFS4ERR_OLD_STATEID
:
345 return ("NFS4ERR_OLD_STATEID");
346 case NFS4ERR_BAD_STATEID
:
347 return ("NFS4ERR_BAD_STATEID");
348 case NFS4ERR_BAD_SEQID
:
349 return ("NFS4ERR_BAD_SEQID");
350 case NFS4ERR_NOT_SAME
:
351 return ("NFS4ERR_NOT_SAME");
352 case NFS4ERR_LOCK_RANGE
:
353 return ("NFS4ERR_LOCK_RANGE");
354 case NFS4ERR_SYMLINK
:
355 return ("NFS4ERR_SYMLINK");
356 case NFS4ERR_RESTOREFH
:
357 return ("NFS4ERR_RESTOREFH");
358 case NFS4ERR_LEASE_MOVED
:
359 return ("NFS4ERR_LEASE_MOVED");
360 case NFS4ERR_ATTRNOTSUPP
:
361 return ("NFS4ERR_ATTRNOTSUPP");
362 case NFS4ERR_NO_GRACE
:
363 return ("NFS4ERR_NO_GRACE");
364 case NFS4ERR_RECLAIM_BAD
:
365 return ("NFS4ERR_RECLAIM_BAD");
366 case NFS4ERR_RECLAIM_CONFLICT
:
367 return ("NFS4ERR_RECLAIM_CONFLICT");
369 return ("NFS4ERR_BADXDR");
370 case NFS4ERR_LOCKS_HELD
:
371 return ("NFS4ERR_LOCKS_HELD");
372 case NFS4ERR_OPENMODE
:
373 return ("NFS4ERR_OPENMODE");
374 case NFS4ERR_BADOWNER
:
375 return ("NFS4ERR_BADOWNER");
376 case NFS4ERR_BADCHAR
:
377 return ("NFS4ERR_BADCHAR");
378 case NFS4ERR_BADNAME
:
379 return ("NFS4ERR_BADNAME");
380 case NFS4ERR_BAD_RANGE
:
381 return ("NFS4ERR_BAD_RANGE");
382 case NFS4ERR_LOCK_NOTSUPP
:
383 return ("NFS4ERR_LOCK_NOTSUPP");
384 case NFS4ERR_OP_ILLEGAL
:
385 return ("NFS4ERR_OP_ILLEGAL");
386 case NFS4ERR_DEADLOCK
:
387 return ("NFS4ERR_DEADLOCK");
388 case NFS4ERR_FILE_OPEN
:
389 return ("NFS4ERR_FILE_OPEN");
390 case NFS4ERR_ADMIN_REVOKED
:
391 return ("NFS4ERR_ADMIN_REVOKED");
392 case NFS4ERR_CB_PATH_DOWN
:
393 return ("NFS4ERR_CB_PATH_DOWN");
395 (void) snprintf(buf
, 40, "Unknown error %d", (int)error
);
401 nfs4_recov_action_to_str(nfs4_recov_t what
)
409 return ("NR_FAILOVER");
411 return ("NR_CLIENTID");
413 return ("NR_OPENFILES");
415 return ("NR_WRONGSEC");
417 return ("NR_EXPIRED");
419 return ("NR_BAD_STATEID");
421 return ("NR_FHEXPIRED");
423 return ("NR_BADHANDLE");
425 return ("NR_BAD_SEQID");
427 return ("NR_OLDSTATEID");
433 return ("NR_LOST_LOCK");
434 case NR_LOST_STATE_RQST
:
435 return ("NR_LOST_STATE_RQST");
439 (void) snprintf(buf
, 40, "Unknown, code %d", (int)what
);
445 nfs4_op_to_str(nfs_opnum4 op
)
449 switch (REAL_OP4(op
)) {
451 return ("OP_ACCESS");
455 return ("OP_COMMIT");
457 return ("OP_CREATE");
459 return ("OP_DELEGPURGE");
461 return ("OP_DELEGRETURN");
463 return ("OP_GETATTR");
475 return ("OP_LOOKUP");
477 return ("OP_LOOKUPP");
479 return ("OP_NVERIFY");
483 return ("OP_OPENATTR");
484 case OP_OPEN_CONFIRM
:
485 return ("OP_OPEN_CONFIRM");
486 case OP_OPEN_DOWNGRADE
:
487 return ("OP_OPEN_DOWNGRADE");
491 return ("OP_PUTPUBFH");
493 return ("OP_PUTROOTFH");
497 return ("OP_READDIR");
499 return ("OP_READLINK");
501 return ("OP_REMOVE");
503 return ("OP_RENAME");
507 return ("OP_RESTOREFH");
509 return ("OP_SAVEFH");
511 return ("OP_SECINFO");
513 return ("OP_SETATTR");
515 return ("OP_SETCLIENTID");
516 case OP_SETCLIENTID_CONFIRM
:
517 return ("OP_SETCLIENTID_CONFIRM");
519 return ("OP_VERIFY");
522 case OP_RELEASE_LOCKOWNER
:
523 return ("OP_RELEASE_LOCKOWNER");
525 return ("OP_ILLEGAL");
527 (void) snprintf(buf
, 40, "Unknown op %d", (int)op
);