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