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 }