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