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