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