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  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  24  * Copyright 2013 Joyent, 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,
  54         NULL
  55 };
  56 
  57 struct modlfs modlfs4 = {
  58         &mod_fsops,
  59         "network filesystem version 4",
  60         &vfw4
  61 };
  62 
  63 volatile uint_t nfs4_max_transfer_size = 32 * 1024;
  64 volatile uint_t nfs4_max_transfer_size_cots = 1024 * 1024;
  65 volatile 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 }