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