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