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