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 /*
  23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "%Z%%M% %I%     %E% SMI"
  28 
  29 #include <fs/fs_subr.h>
  30 #include <sys/atomic.h>
  31 #include <sys/cmn_err.h>
  32 #include <sys/dirent.h>
  33 #include <sys/fs/fifonode.h>
  34 #include <sys/modctl.h>
  35 #include <sys/mount.h>
  36 #include <sys/policy.h>
  37 #include <sys/sunddi.h>
  38 
  39 #include <sys/sysmacros.h>
  40 #include <sys/vfs.h>
  41 #include <sys/vfs_opreg.h>
  42 
  43 #include <sys/lx_autofs_impl.h>
  44 
  45 /*
  46  * External functions
  47  */
  48 extern uintptr_t                space_fetch(char *key);
  49 extern int                      space_store(char *key, uintptr_t ptr);
  50 
  51 /*
  52  * Globals
  53  */
  54 static vfsops_t                 *lx_autofs_vfsops;
  55 static vnodeops_t               *lx_autofs_vn_ops = NULL;
  56 static int                      lx_autofs_fstype;
  57 static major_t                  lx_autofs_major;
  58 static minor_t                  lx_autofs_minor = 0;
  59 
  60 /*
  61  * Support functions
  62  */
  63 static void
  64 i_strfree(char *str)
  65 {
  66         kmem_free(str, strlen(str) + 1);
  67 }
  68 
  69 static char *
  70 i_strdup(char *str)
  71 {
  72         int     n = strlen(str);
  73         char    *ptr = kmem_alloc(n + 1, KM_SLEEP);
  74         bcopy(str, ptr, n + 1);
  75         return (ptr);
  76 }
  77 
  78 static int
  79 i_str_to_int(char *str, int *val)
  80 {
  81         long    res;
  82 
  83         if (str == NULL)
  84                 return (-1);
  85 
  86         if ((ddi_strtol(str, NULL, 10, &res) != 0) ||
  87             (res < INT_MIN) || (res > INT_MAX))
  88                 return (-1);
  89 
  90         *val = res;
  91         return (0);
  92 }
  93 
  94 static void
  95 i_stack_init(list_t *lp)
  96 {
  97         list_create(lp,
  98             sizeof (stack_elem_t), offsetof(stack_elem_t, se_list));
  99 }
 100 
 101 static void
 102 i_stack_fini(list_t *lp)
 103 {
 104         ASSERT(list_head(lp) == NULL);
 105         list_destroy(lp);
 106 }
 107 
 108 static void
 109 i_stack_push(list_t *lp, caddr_t ptr1, caddr_t ptr2, caddr_t ptr3)
 110 {
 111         stack_elem_t    *se;
 112 
 113         se = kmem_alloc(sizeof (*se), KM_SLEEP);
 114         se->se_ptr1 = ptr1;
 115         se->se_ptr2 = ptr2;
 116         se->se_ptr3 = ptr3;
 117         list_insert_head(lp, se);
 118 }
 119 
 120 static int
 121 i_stack_pop(list_t *lp, caddr_t *ptr1, caddr_t *ptr2, caddr_t *ptr3)
 122 {
 123         stack_elem_t    *se;
 124 
 125         if ((se = list_head(lp)) == NULL)
 126                 return (-1);
 127         list_remove(lp, se);
 128         if (ptr1 != NULL)
 129                 *ptr1 = se->se_ptr1;
 130         if (ptr2 != NULL)
 131                 *ptr2 = se->se_ptr2;
 132         if (ptr3 != NULL)
 133                 *ptr3 = se->se_ptr3;
 134         kmem_free(se, sizeof (*se));
 135         return (0);
 136 }
 137 
 138 static vnode_t *
 139 fifo_peer_vp(vnode_t *vp)
 140 {
 141         fifonode_t *fnp = VTOF(vp);
 142         fifonode_t *fn_dest = fnp->fn_dest;
 143         return (FTOV(fn_dest));
 144 }
 145 
 146 static vnode_t *
 147 i_vn_alloc(vfs_t *vfsp, vnode_t *uvp)
 148 {
 149         lx_autofs_vfs_t *data = vfsp->vfs_data;
 150         vnode_t         *vp, *vp_old;
 151 
 152         /* Allocate a new vnode structure in case we need it. */
 153         vp = vn_alloc(KM_SLEEP);
 154         vn_setops(vp, lx_autofs_vn_ops);
 155         VN_SET_VFS_TYPE_DEV(vp, vfsp, uvp->v_type, uvp->v_rdev);
 156         vp->v_data = uvp;
 157         ASSERT(vp->v_count == 1);
 158 
 159         /*
 160          * Take a hold on the vfs structure.  This is how unmount will
 161          * determine if there are any active vnodes in the file system.
 162          */
 163         VFS_HOLD(vfsp);
 164 
 165         /*
 166          * Check if we already have a vnode allocated for this underlying
 167          * vnode_t.
 168          */
 169         mutex_enter(&data->lav_lock);
 170         if (mod_hash_find(data->lav_vn_hash,
 171             (mod_hash_key_t)uvp, (mod_hash_val_t *)&vp_old) != 0) {
 172 
 173                 /*
 174                  * Didn't find an existing node.
 175                  * Add this node to the hash and return.
 176                  */
 177                 VERIFY(mod_hash_insert(data->lav_vn_hash,
 178                     (mod_hash_key_t)uvp,
 179                     (mod_hash_val_t)vp) == 0);
 180                 mutex_exit(&data->lav_lock);
 181                 return (vp);
 182         }
 183 
 184         /* Get a hold on the existing vnode and free up the one we allocated. */
 185         VN_HOLD(vp_old);
 186         mutex_exit(&data->lav_lock);
 187 
 188         /* Free up the new vnode we allocated. */
 189         VN_RELE(uvp);
 190         VFS_RELE(vfsp);
 191         vn_invalid(vp);
 192         vn_free(vp);
 193 
 194         return (vp_old);
 195 }
 196 
 197 static void
 198 i_vn_free(vnode_t *vp)
 199 {
 200         vfs_t           *vfsp = vp->v_vfsp;
 201         lx_autofs_vfs_t *data = vfsp->vfs_data;
 202         vnode_t         *uvp = vp->v_data;
 203         vnode_t *vp_tmp;
 204 
 205         ASSERT(MUTEX_HELD((&data->lav_lock)));
 206         ASSERT(MUTEX_HELD((&vp->v_lock)));
 207 
 208         ASSERT(vp->v_count == 0);
 209 
 210         /* We're about to free this vnode so take it out of the hash. */
 211         (void) mod_hash_remove(data->lav_vn_hash,
 212             (mod_hash_key_t)uvp, (mod_hash_val_t)&vp_tmp);
 213 
 214         /*
 215          * No one else can lookup this vnode any more so there's no need
 216          * to hold locks.
 217          */
 218         mutex_exit(&data->lav_lock);
 219         mutex_exit(&vp->v_lock);
 220 
 221         /* Release the underlying vnode. */
 222         VN_RELE(uvp);
 223         VFS_RELE(vfsp);
 224         vn_invalid(vp);
 225         vn_free(vp);
 226 }
 227 
 228 static lx_autofs_lookup_req_t *
 229 i_lalr_alloc(lx_autofs_vfs_t *data, int *dup_request, char *nm)
 230 {
 231         lx_autofs_lookup_req_t  *lalr, *lalr_dup;
 232 
 233         /* Pre-allocate a new automounter request before grabbing locks. */
 234         lalr = kmem_zalloc(sizeof (*lalr), KM_SLEEP);
 235         mutex_init(&lalr->lalr_lock, NULL, MUTEX_DEFAULT, NULL);
 236         cv_init(&lalr->lalr_cv, NULL, CV_DEFAULT, NULL);
 237         lalr->lalr_ref = 1;
 238         lalr->lalr_pkt.lap_protover = LX_AUTOFS_PROTO_VERSION;
 239 
 240         /* Assign a unique id for this request. */
 241         lalr->lalr_pkt.lap_id = id_alloc(data->lav_ids);
 242 
 243         /*
 244          * The token expected by the linux automount is the name of
 245          * the directory entry to look up.  (And not the entire
 246          * path that is being accessed.)
 247          */
 248         lalr->lalr_pkt.lap_name_len = strlen(nm);
 249         if (lalr->lalr_pkt.lap_name_len >
 250             (sizeof (lalr->lalr_pkt.lap_name) - 1)) {
 251                 zcmn_err(getzoneid(), CE_NOTE,
 252                     "invalid autofs lookup: \"%s\"", nm);
 253                 id_free(data->lav_ids, lalr->lalr_pkt.lap_id);
 254                 kmem_free(lalr, sizeof (*lalr));
 255                 return (NULL);
 256         }
 257         (void) strlcpy(lalr->lalr_pkt.lap_name, nm,
 258             sizeof (lalr->lalr_pkt.lap_name));
 259 
 260         /* Check for an outstanding request for this path. */
 261         mutex_enter(&data->lav_lock);
 262         if (mod_hash_find(data->lav_path_hash,
 263             (mod_hash_key_t)nm, (mod_hash_val_t *)&lalr_dup) == 0) {
 264                 /*
 265                  * There's already an outstanding request for this
 266                  * path so we don't need a new one.
 267                  */
 268                 id_free(data->lav_ids, lalr->lalr_pkt.lap_id);
 269                 kmem_free(lalr, sizeof (*lalr));
 270                 lalr = lalr_dup;
 271 
 272                 /* Bump the ref count on the old request. */
 273                 atomic_add_int(&lalr->lalr_ref, 1);
 274 
 275                 *dup_request = 1;
 276         } else {
 277                 /* Add it to the hashes. */
 278                 VERIFY(mod_hash_insert(data->lav_id_hash,
 279                     (mod_hash_key_t)(uintptr_t)lalr->lalr_pkt.lap_id,
 280                     (mod_hash_val_t)lalr) == 0);
 281                 VERIFY(mod_hash_insert(data->lav_path_hash,
 282                     (mod_hash_key_t)i_strdup(nm),
 283                     (mod_hash_val_t)lalr) == 0);
 284 
 285                 *dup_request = 0;
 286         }
 287         mutex_exit(&data->lav_lock);
 288 
 289         return (lalr);
 290 }
 291 
 292 static lx_autofs_lookup_req_t *
 293 i_lalr_find(lx_autofs_vfs_t *data, int id)
 294 {
 295         lx_autofs_lookup_req_t  *lalr;
 296 
 297         /* Check for an outstanding request for this id. */
 298         mutex_enter(&data->lav_lock);
 299         if (mod_hash_find(data->lav_id_hash, (mod_hash_key_t)(uintptr_t)id,
 300             (mod_hash_val_t *)&lalr) != 0) {
 301                 mutex_exit(&data->lav_lock);
 302                 return (NULL);
 303         }
 304         atomic_add_int(&lalr->lalr_ref, 1);
 305         mutex_exit(&data->lav_lock);
 306         return (lalr);
 307 }
 308 
 309 static void
 310 i_lalr_complete(lx_autofs_vfs_t *data, lx_autofs_lookup_req_t *lalr)
 311 {
 312         lx_autofs_lookup_req_t  *lalr_tmp;
 313 
 314         /* Remove this request from the hashes so no one can look it up. */
 315         mutex_enter(&data->lav_lock);
 316         (void) mod_hash_remove(data->lav_id_hash,
 317                     (mod_hash_key_t)(uintptr_t)lalr->lalr_pkt.lap_id,
 318                     (mod_hash_val_t)&lalr_tmp);
 319         (void) mod_hash_remove(data->lav_path_hash,
 320                     (mod_hash_key_t)lalr->lalr_pkt.lap_name,
 321                     (mod_hash_val_t)&lalr_tmp);
 322         mutex_exit(&data->lav_lock);
 323 
 324         /* Mark this requst as complete and wakeup anyone waiting on it. */
 325         mutex_enter(&lalr->lalr_lock);
 326         lalr->lalr_complete = 1;
 327         cv_broadcast(&lalr->lalr_cv);
 328         mutex_exit(&lalr->lalr_lock);
 329 }
 330 
 331 static void
 332 i_lalr_release(lx_autofs_vfs_t *data, lx_autofs_lookup_req_t *lalr)
 333 {
 334         ASSERT(!MUTEX_HELD(&lalr->lalr_lock));
 335         if (atomic_add_int_nv(&lalr->lalr_ref, -1) > 0)
 336                 return;
 337         ASSERT(lalr->lalr_ref == 0);
 338         id_free(data->lav_ids, lalr->lalr_pkt.lap_id);
 339         kmem_free(lalr, sizeof (*lalr));
 340 }
 341 
 342 static void
 343 i_lalr_abort(lx_autofs_vfs_t *data, lx_autofs_lookup_req_t *lalr)
 344 {
 345         lx_autofs_lookup_req_t  *lalr_tmp;
 346 
 347         /*
 348          * This is a little tricky.  We're aborting the wait for this
 349          * request.  So if anyone else is waiting for this request we
 350          * can't free it, but if no one else is waiting for the request
 351          * we should free it.
 352          */
 353         mutex_enter(&data->lav_lock);
 354         if (atomic_add_int_nv(&lalr->lalr_ref, -1) > 0) {
 355                 mutex_exit(&data->lav_lock);
 356                 return;
 357         }
 358         ASSERT(lalr->lalr_ref == 0);
 359 
 360         /* Remove this request from the hashes so no one can look it up. */
 361         (void) mod_hash_remove(data->lav_id_hash,
 362                     (mod_hash_key_t)(uintptr_t)lalr->lalr_pkt.lap_id,
 363                     (mod_hash_val_t)&lalr_tmp);
 364         (void) mod_hash_remove(data->lav_path_hash,
 365                     (mod_hash_key_t)lalr->lalr_pkt.lap_name,
 366                     (mod_hash_val_t)&lalr_tmp);
 367         mutex_exit(&data->lav_lock);
 368 
 369         /* It's ok to free this now because the ref count was zero. */
 370         id_free(data->lav_ids, lalr->lalr_pkt.lap_id);
 371         kmem_free(lalr, sizeof (*lalr));
 372 }
 373 
 374 static int
 375 i_fifo_lookup(pid_t pgrp, int fd, file_t **fpp_wr, file_t **fpp_rd)
 376 {
 377         proc_t          *prp;
 378         uf_info_t       *fip;
 379         uf_entry_t      *ufp_wr, *ufp_rd = NULL;
 380         file_t          *fp_wr, *fp_rd = NULL;
 381         vnode_t         *vp_wr, *vp_rd;
 382         int             i;
 383 
 384         /*
 385          * sprlock() is zone aware, so assuming this mount call was
 386          * initiated by a process in a zone, if it tries to specify
 387          * a pgrp outside of it's zone this call will fail.
 388          *
 389          * Also, we want to grab hold of the main automounter process
 390          * and its going to be the group leader for pgrp, so its
 391          * pid will be equal to pgrp.
 392          */
 393         prp = sprlock(pgrp);
 394         if (prp == NULL)
 395                 return (-1);
 396         mutex_exit(&prp->p_lock);
 397 
 398         /* Now we want to access the processes open file descriptors. */
 399         fip = P_FINFO(prp);
 400         mutex_enter(&fip->fi_lock);
 401 
 402         /* Sanity check fifo write fd. */
 403         if (fd >= fip->fi_nfiles) {
 404                 mutex_exit(&fip->fi_lock);
 405                 mutex_enter(&prp->p_lock);
 406                 sprunlock(prp);
 407                 return (-1);
 408         }
 409 
 410         /* Get a pointer to the write fifo. */
 411         UF_ENTER(ufp_wr, fip, fd);
 412         if (((fp_wr = ufp_wr->uf_file) == NULL) ||
 413             ((vp_wr = fp_wr->f_vnode) == NULL) || (vp_wr->v_type != VFIFO)) {
 414                 /* Invalid fifo fd. */
 415                 UF_EXIT(ufp_wr);
 416                 mutex_exit(&fip->fi_lock);
 417                 mutex_enter(&prp->p_lock);
 418                 sprunlock(prp);
 419                 return (-1);
 420         }
 421 
 422         /*
 423          * Now we need to find the read end of the fifo (for reasons
 424          * explained below.)  We assume that the read end of the fifo
 425          * is in the same process as the write end.
 426          */
 427         vp_rd = fifo_peer_vp(fp_wr->f_vnode);
 428         for (i = 0; i < fip->fi_nfiles; i++) {
 429                 UF_ENTER(ufp_rd, fip, i);
 430                 if (((fp_rd = ufp_rd->uf_file) != NULL) &&
 431                     (fp_rd->f_vnode == vp_rd))
 432                         break;
 433                 UF_EXIT(ufp_rd);
 434         }
 435         if (i == fip->fi_nfiles) {
 436                 /* Didn't find it. */
 437                 UF_EXIT(ufp_wr);
 438                 mutex_exit(&fip->fi_lock);
 439                 mutex_enter(&prp->p_lock);
 440                 sprunlock(prp);
 441                 return (-1);
 442         }
 443 
 444         /*
 445          * We need to drop fi_lock before we can try to acquire f_tlock
 446          * the good news is that the file pointers are protected because
 447          * we're still holding uf_lock.
 448          */
 449         mutex_exit(&fip->fi_lock);
 450 
 451         /*
 452          * Here we bump the open counts on the fifos.  The reason
 453          * that we do this is because when we go to write to the
 454          * fifo we want to ensure that they are actually open (and
 455          * not in the process of being closed) without having to
 456          * stop the automounter.  (If the write end of the fifo
 457          * were closed and we tried to write to it we would panic.
 458          * If the read end of the fifo was closed and we tried to
 459          * write to the other end, the process that invoked the
 460          * lookup operation would get an unexpected SIGPIPE.)
 461          */
 462         mutex_enter(&fp_wr->f_tlock);
 463         fp_wr->f_count++;
 464         ASSERT(fp_wr->f_count >= 2);
 465         mutex_exit(&fp_wr->f_tlock);
 466 
 467         mutex_enter(&fp_rd->f_tlock);
 468         fp_rd->f_count++;
 469         ASSERT(fp_rd->f_count >= 2);
 470         mutex_exit(&fp_rd->f_tlock);
 471 
 472         /* Release all our locks. */
 473         UF_EXIT(ufp_wr);
 474         UF_EXIT(ufp_rd);
 475         mutex_enter(&prp->p_lock);
 476         sprunlock(prp);
 477 
 478         /* Return the file pointers. */
 479         *fpp_rd = fp_rd;
 480         *fpp_wr = fp_wr;
 481         return (0);
 482 }
 483 
 484 static uint_t
 485 /*ARGSUSED*/
 486 i_fifo_close_cb(mod_hash_key_t key, mod_hash_val_t *val, void *arg)
 487 {
 488         int     *id = (int *)arg;
 489         /* Return the key and terminate the walk. */
 490         *id = (uintptr_t)key;
 491         return (MH_WALK_TERMINATE);
 492 }
 493 
 494 static void
 495 i_fifo_close(lx_autofs_vfs_t *data)
 496 {
 497         /*
 498          * Close the fifo to prevent any future requests from
 499          * getting sent to the automounter.
 500          */
 501         mutex_enter(&data->lav_lock);
 502         if (data->lav_fifo_wr != NULL) {
 503                 (void) closef(data->lav_fifo_wr);
 504                 data->lav_fifo_wr = NULL;
 505         }
 506         if (data->lav_fifo_rd != NULL) {
 507                 (void) closef(data->lav_fifo_rd);
 508                 data->lav_fifo_rd = NULL;
 509         }
 510         mutex_exit(&data->lav_lock);
 511 
 512         /*
 513          * Wakeup any threads currently waiting for the automounter
 514          * note that it's possible for multiple threads to have entered
 515          * this function and to be doing the work below simultaneously.
 516          */
 517         for (;;) {
 518                 lx_autofs_lookup_req_t  *lalr;
 519                 int                     id;
 520 
 521                 /* Lookup the first entry in the hash. */
 522                 id = -1;
 523                 mod_hash_walk(data->lav_id_hash,
 524                     i_fifo_close_cb, &id);
 525                 if (id == -1) {
 526                         /* No more id's in the hash. */
 527                         break;
 528                 }
 529                 if ((lalr = i_lalr_find(data, id)) == NULL) {
 530                         /* Someone else beat us to it. */
 531                         continue;
 532                 }
 533 
 534                 /* Mark the request as compleate and release it. */
 535                 i_lalr_complete(data, lalr);
 536                 i_lalr_release(data, lalr);
 537         }
 538 }
 539 
 540 static int
 541 i_fifo_verify_rd(lx_autofs_vfs_t *data)
 542 {
 543         proc_t          *prp;
 544         uf_info_t       *fip;
 545         uf_entry_t      *ufp_rd = NULL;
 546         file_t          *fp_rd =  NULL;
 547         vnode_t         *vp_rd;
 548         int             i;
 549 
 550         ASSERT(MUTEX_HELD((&data->lav_lock)));
 551 
 552         /* Check if we've already been shut down. */
 553         if (data->lav_fifo_wr == NULL) {
 554                 ASSERT(data->lav_fifo_rd == NULL);
 555                 return (-1);
 556         }
 557         vp_rd = fifo_peer_vp(data->lav_fifo_wr->f_vnode);
 558 
 559         /*
 560          * sprlock() is zone aware, so assuming this mount call was
 561          * initiated by a process in a zone, if it tries to specify
 562          * a pgrp outside of it's zone this call will fail.
 563          *
 564          * Also, we want to grab hold of the main automounter process
 565          * and its going to be the group leader for pgrp, so its
 566          * pid will be equal to pgrp.
 567          */
 568         prp = sprlock(data->lav_pgrp);
 569         if (prp == NULL)
 570                 return (-1);
 571         mutex_exit(&prp->p_lock);
 572 
 573         /* Now we want to access the processes open file descriptors. */
 574         fip = P_FINFO(prp);
 575         mutex_enter(&fip->fi_lock);
 576 
 577         /*
 578          * Now we need to find the read end of the fifo (for reasons
 579          * explained below.)  We assume that the read end of the fifo
 580          * is in the same process as the write end.
 581          */
 582         for (i = 0; i < fip->fi_nfiles; i++) {
 583                 UF_ENTER(ufp_rd, fip, i);
 584                 if (((fp_rd = ufp_rd->uf_file) != NULL) &&
 585                     (fp_rd->f_vnode == vp_rd))
 586                         break;
 587                 UF_EXIT(ufp_rd);
 588         }
 589         if (i == fip->fi_nfiles) {
 590                 /* Didn't find it. */
 591                 mutex_exit(&fip->fi_lock);
 592                 mutex_enter(&prp->p_lock);
 593                 sprunlock(prp);
 594                 return (-1);
 595         }
 596 
 597         /*
 598          * Seems the automounter still has the read end of the fifo
 599          * open, we're done here.  Release all our locks and exit.
 600          */
 601         mutex_exit(&fip->fi_lock);
 602         UF_EXIT(ufp_rd);
 603         mutex_enter(&prp->p_lock);
 604         sprunlock(prp);
 605 
 606         return (0);
 607 }
 608 
 609 static int
 610 i_fifo_write(lx_autofs_vfs_t *data, lx_autofs_pkt_t *lap)
 611 {
 612         struct uio      uio;
 613         struct iovec    iov;
 614         file_t          *fp_wr, *fp_rd;
 615         int             error;
 616 
 617         /*
 618          * The catch here is we need to make sure _we_ don't close
 619          * the the fifo while writing to it.  (Another thread could come
 620          * along and realize the automounter process is gone and close
 621          * the fifo.  To do this we bump the open count before we
 622          * write to the fifo.
 623          */
 624         mutex_enter(&data->lav_lock);
 625         if (data->lav_fifo_wr == NULL) {
 626                 ASSERT(data->lav_fifo_rd == NULL);
 627                 mutex_exit(&data->lav_lock);
 628                 return (ENOENT);
 629         }
 630         fp_wr = data->lav_fifo_wr;
 631         fp_rd = data->lav_fifo_rd;
 632 
 633         /* Bump the open count on the write fifo. */
 634         mutex_enter(&fp_wr->f_tlock);
 635         fp_wr->f_count++;
 636         mutex_exit(&fp_wr->f_tlock);
 637 
 638         /* Bump the open count on the read fifo. */
 639         mutex_enter(&fp_rd->f_tlock);
 640         fp_rd->f_count++;
 641         mutex_exit(&fp_rd->f_tlock);
 642 
 643         mutex_exit(&data->lav_lock);
 644 
 645         iov.iov_base = (caddr_t)lap;
 646         iov.iov_len = sizeof (*lap);
 647         uio.uio_iov = &iov;
 648         uio.uio_iovcnt = 1;
 649         uio.uio_loffset = 0;
 650         uio.uio_segflg = (short)UIO_SYSSPACE;
 651         uio.uio_resid = sizeof (*lap);
 652         uio.uio_llimit = 0;
 653         uio.uio_fmode = FWRITE | FNDELAY | FNONBLOCK;
 654 
 655         error = VOP_WRITE(fp_wr->f_vnode, &uio, 0, kcred, NULL);
 656         (void) closef(fp_wr);
 657         (void) closef(fp_rd);
 658 
 659         /*
 660          * After every write we verify that the automounter still has
 661          * these files open.
 662          */
 663         mutex_enter(&data->lav_lock);
 664         if (i_fifo_verify_rd(data) != 0) {
 665                 /*
 666                  * Something happened to the automounter.
 667                  * Close down the communication pipe we setup.
 668                  */
 669                 mutex_exit(&data->lav_lock);
 670                 i_fifo_close(data);
 671                 if (error != 0)
 672                         return (error);
 673                 return (ENOENT);
 674         }
 675         mutex_exit(&data->lav_lock);
 676 
 677         return (error);
 678 }
 679 
 680 static int
 681 i_bs_readdir(vnode_t *dvp, list_t *dir_stack, list_t *file_stack)
 682 {
 683         struct iovec    iov;
 684         struct uio      uio;
 685         dirent64_t      *dp, *dbuf;
 686         vnode_t         *vp;
 687         size_t          dlen, dbuflen;
 688         int             eof, error, ndirents = 64;
 689         char            *nm;
 690 
 691         dlen = ndirents * (sizeof (*dbuf));
 692         dbuf = kmem_alloc(dlen, KM_SLEEP);
 693 
 694         uio.uio_iov = &iov;
 695         uio.uio_iovcnt = 1;
 696         uio.uio_segflg = UIO_SYSSPACE;
 697         uio.uio_fmode = 0;
 698         uio.uio_extflg = UIO_COPY_CACHED;
 699         uio.uio_loffset = 0;
 700         uio.uio_llimit = MAXOFFSET_T;
 701 
 702         eof = 0;
 703         error = 0;
 704         while (!error && !eof) {
 705                 uio.uio_resid = dlen;
 706                 iov.iov_base = (char *)dbuf;
 707                 iov.iov_len = dlen;
 708 
 709                 (void) VOP_RWLOCK(dvp, V_WRITELOCK_FALSE, NULL);
 710                 if (VOP_READDIR(dvp, &uio, kcred, &eof, NULL, 0) != 0) {
 711                         VOP_RWUNLOCK(dvp, V_WRITELOCK_FALSE, NULL);
 712                         kmem_free(dbuf, dlen);
 713                         return (-1);
 714                 }
 715                 VOP_RWUNLOCK(dvp, V_WRITELOCK_FALSE, NULL);
 716 
 717                 if ((dbuflen = dlen - uio.uio_resid) == 0) {
 718                         /* We're done. */
 719                         break;
 720                 }
 721 
 722                 for (dp = dbuf; ((intptr_t)dp < (intptr_t)dbuf + dbuflen);
 723                         dp = (dirent64_t *)((intptr_t)dp + dp->d_reclen)) {
 724 
 725                         nm = dp->d_name;
 726 
 727                         if (strcmp(nm, ".") == 0 || strcmp(nm, "..") == 0)
 728                                 continue;
 729 
 730                         if (VOP_LOOKUP(dvp, nm, &vp, NULL, 0, NULL, kcred,
 731                             NULL, NULL, NULL) != 0) {
 732                                 kmem_free(dbuf, dlen);
 733                                 return (-1);
 734                         }
 735                         if (vp->v_type == VDIR) {
 736                                 if (dir_stack != NULL) {
 737                                         i_stack_push(dir_stack, (caddr_t)dvp,
 738                                             (caddr_t)vp, i_strdup(nm));
 739                                 } else {
 740                                         VN_RELE(vp);
 741                                 }
 742                         } else {
 743                                 if (file_stack != NULL) {
 744                                         i_stack_push(file_stack, (caddr_t)dvp,
 745                                             (caddr_t)vp, i_strdup(nm));
 746                                 } else {
 747                                         VN_RELE(vp);
 748                                 }
 749                         }
 750                 }
 751         }
 752         kmem_free(dbuf, dlen);
 753         return (0);
 754 }
 755 
 756 static void
 757 i_bs_destroy(vnode_t *dvp, char *path)
 758 {
 759         list_t  search_stack;
 760         list_t  dir_stack;
 761         list_t  file_stack;
 762         vnode_t *pdvp, *vp;
 763         char    *dpath, *fpath;
 764         int     ret;
 765 
 766         if (VOP_LOOKUP(dvp, path, &vp, NULL, 0, NULL, kcred,
 767             NULL, NULL, NULL) != 0) {
 768                 /* A directory entry with this name doesn't actually exist. */
 769                 return;
 770         }
 771 
 772         if ((vp->v_type & VDIR) == 0) {
 773                 /* Easy, the directory entry is a file so delete it. */
 774                 VN_RELE(vp);
 775                 (void) VOP_REMOVE(dvp, path, kcred, NULL, 0);
 776                 return;
 777         }
 778 
 779         /*
 780          * The directory entry is a subdirectory, now we have a bit more
 781          * work to do.  (We'll have to recurse into the sub directory.)
 782          * It would have been much easier to do this recursively but kernel
 783          * stacks are notoriously small.
 784          */
 785         i_stack_init(&search_stack);
 786         i_stack_init(&dir_stack);
 787         i_stack_init(&file_stack);
 788 
 789         /* Save our newfound subdirectory into a list. */
 790         i_stack_push(&search_stack, (caddr_t)dvp, (caddr_t)vp, i_strdup(path));
 791 
 792         /* Do a recursive depth first search into the subdirectories. */
 793         while (i_stack_pop(&search_stack,
 794             (caddr_t *)&pdvp, (caddr_t *)&dvp, &dpath) == 0) {
 795 
 796                 /* Get a list of the subdirectories in this directory. */
 797                 if (i_bs_readdir(dvp, &search_stack, NULL) != 0)
 798                         goto exit;
 799 
 800                 /* Save the current directory a separate stack. */
 801                 i_stack_push(&dir_stack, (caddr_t)pdvp, (caddr_t)dvp, dpath);
 802         }
 803 
 804         /*
 805          * Now dir_stack contains a list of directories, the deepest paths
 806          * are at the top of the list.  So let's go through and process them.
 807          */
 808         while (i_stack_pop(&dir_stack,
 809             (caddr_t *)&pdvp, (caddr_t *)&dvp, &dpath) == 0) {
 810 
 811                 /* Get a list of the files in this directory. */
 812                 if (i_bs_readdir(dvp, NULL, &file_stack) != 0) {
 813                         VN_RELE(dvp);
 814                         i_strfree(dpath);
 815                         goto exit;
 816                 }
 817 
 818                 /* Delete all the files in this directory. */
 819                 while (i_stack_pop(&file_stack,
 820                     NULL, (caddr_t *)&vp, &fpath) == 0) {
 821                         VN_RELE(vp)
 822                         ret = VOP_REMOVE(dvp, fpath, kcred, NULL, 0);
 823                         i_strfree(fpath);
 824                         if (ret != 0) {
 825                                 i_strfree(dpath);
 826                                 goto exit;
 827                         }
 828                 }
 829 
 830                 /* Delete this directory. */
 831                 VN_RELE(dvp);
 832                 ret = VOP_RMDIR(pdvp, dpath, pdvp, kcred, NULL, 0);
 833                 i_strfree(dpath);
 834                 if (ret != 0)
 835                         goto exit;
 836         }
 837 
 838 exit:
 839         while (
 840             (i_stack_pop(&search_stack, NULL, (caddr_t *)&vp, &path) == 0) ||
 841             (i_stack_pop(&dir_stack, NULL, (caddr_t *)&vp, &path) == 0) ||
 842             (i_stack_pop(&file_stack, NULL, (caddr_t *)&vp, &path) == 0)) {
 843                 VN_RELE(vp);
 844                 i_strfree(path);
 845         }
 846         i_stack_fini(&search_stack);
 847         i_stack_fini(&dir_stack);
 848         i_stack_fini(&file_stack);
 849 }
 850 
 851 static vnode_t *
 852 i_bs_create(vnode_t *dvp, char *bs_name)
 853 {
 854         vnode_t *vp;
 855         vattr_t vattr;
 856 
 857         /*
 858          * After looking at the mkdir syscall path it seems we don't need
 859          * to initialize all of the vattr_t structure.
 860          */
 861         bzero(&vattr, sizeof (vattr));
 862         vattr.va_type = VDIR;
 863         vattr.va_mode = 0755; /* u+rwx,og=rx */
 864         vattr.va_mask = AT_TYPE|AT_MODE;
 865 
 866         if (VOP_MKDIR(dvp, bs_name, &vattr, &vp, kcred, NULL, 0, NULL) != 0)
 867                 return (NULL);
 868         return (vp);
 869 }
 870 
 871 static int
 872 i_automounter_call(vnode_t *dvp, char *nm)
 873 {
 874         lx_autofs_lookup_req_t  *lalr;
 875         lx_autofs_vfs_t         *data;
 876         int                     error, dup_request;
 877 
 878         /* Get a pointer to the vfs mount data. */
 879         data = dvp->v_vfsp->vfs_data;
 880 
 881         /* The automounter only support queries in the root directory. */
 882         if (dvp != data->lav_root)
 883                 return (ENOENT);
 884 
 885         /*
 886          * Check if the current process is in the automounters process
 887          * group.  (If it is, the current process is either the autmounter
 888          * itself or one of it's forked child processes.)  If so, don't
 889          * redirect this lookup back into the automounter because we'll
 890          * hang.
 891          */
 892         mutex_enter(&pidlock);
 893         if (data->lav_pgrp == curproc->p_pgrp) {
 894                 mutex_exit(&pidlock);
 895                 return (ENOENT);
 896         }
 897         mutex_exit(&pidlock);
 898 
 899         /* Verify that the automount process pipe still exists. */
 900         mutex_enter(&data->lav_lock);
 901         if (data->lav_fifo_wr == NULL) {
 902                 ASSERT(data->lav_fifo_rd == NULL);
 903                 mutex_exit(&data->lav_lock);
 904                 return (ENOENT);
 905         }
 906         mutex_exit(&data->lav_lock);
 907 
 908         /* Allocate an automounter request structure. */
 909         if ((lalr = i_lalr_alloc(data, &dup_request, nm)) == NULL)
 910                 return (ENOENT);
 911 
 912         /*
 913          * If we were the first one to allocate this request then we
 914          * need to send it to the automounter.
 915          */
 916         if ((!dup_request) &&
 917             ((error = i_fifo_write(data, &lalr->lalr_pkt)) != 0)) {
 918                 /*
 919                  * Unable to send the request to the automounter.
 920                  * Unblock any other threads waiting on the request
 921                  * and release the request.
 922                  */
 923                 i_lalr_complete(data, lalr);
 924                 i_lalr_release(data, lalr);
 925                 return (error);
 926         }
 927 
 928         /* Wait for someone to signal us that this request has compleated. */
 929         mutex_enter(&lalr->lalr_lock);
 930         while (!lalr->lalr_complete) {
 931                 if (cv_wait_sig(&lalr->lalr_cv, &lalr->lalr_lock) == 0) {
 932                         /* We got a signal, abort this lookup. */
 933                         mutex_exit(&lalr->lalr_lock);
 934                         i_lalr_abort(data, lalr);
 935                         return (EINTR);
 936                 }
 937         }
 938         mutex_exit(&lalr->lalr_lock);
 939         i_lalr_release(data, lalr);
 940 
 941         return (0);
 942 }
 943 
 944 static int
 945 i_automounter_ioctl(vnode_t *vp, int cmd, intptr_t arg)
 946 {
 947         lx_autofs_vfs_t *data = (lx_autofs_vfs_t *)vp->v_vfsp->vfs_data;
 948 
 949         /*
 950          * Be strict.
 951          * We only accept ioctls from the automounter process group.
 952          */
 953         mutex_enter(&pidlock);
 954         if (data->lav_pgrp != curproc->p_pgrp) {
 955                 mutex_exit(&pidlock);
 956                 return (ENOENT);
 957         }
 958         mutex_exit(&pidlock);
 959 
 960         if ((cmd == LX_AUTOFS_IOC_READY) || (cmd == LX_AUTOFS_IOC_FAIL)) {
 961                 lx_autofs_lookup_req_t  *lalr;
 962                 int                     id = arg;
 963 
 964                 /*
 965                  * We don't actually care if the request failed or succeeded.
 966                  * We do the same thing either way.
 967                  */
 968                 if ((lalr = i_lalr_find(data, id)) == NULL)
 969                         return (ENXIO);
 970 
 971                 /* Mark the request as compleate and release it. */
 972                 i_lalr_complete(data, lalr);
 973                 i_lalr_release(data, lalr);
 974                 return (0);
 975         }
 976         if (cmd == LX_AUTOFS_IOC_CATATONIC) {
 977                 /* The automounter is shutting down. */
 978                 i_fifo_close(data);
 979                 return (0);
 980         }
 981         return (ENOTSUP);
 982 }
 983 
 984 static int
 985 i_parse_mntopt(vfs_t *vfsp, lx_autofs_vfs_t *data)
 986 {
 987         char            *fd_str, *pgrp_str, *minproto_str, *maxproto_str;
 988         int             fd, pgrp, minproto, maxproto;
 989         file_t          *fp_wr, *fp_rd;
 990 
 991         /* Require all options to be present. */
 992         if ((vfs_optionisset(vfsp, LX_MNTOPT_FD, &fd_str) != 1) ||
 993             (vfs_optionisset(vfsp, LX_MNTOPT_PGRP, &pgrp_str) != 1) ||
 994             (vfs_optionisset(vfsp, LX_MNTOPT_MINPROTO, &minproto_str) != 1) ||
 995             (vfs_optionisset(vfsp, LX_MNTOPT_MAXPROTO, &maxproto_str) != 1))
 996                 return (EINVAL);
 997 
 998         /* Get the values for each parameter. */
 999         if ((i_str_to_int(fd_str, &fd) != 0) ||
1000             (i_str_to_int(pgrp_str, &pgrp) != 0) ||
1001             (i_str_to_int(minproto_str, &minproto) != 0) ||
1002             (i_str_to_int(maxproto_str, &maxproto) != 0))
1003                 return (EINVAL);
1004 
1005         /*
1006          * We support v2 of the linux kernel automounter protocol.
1007          * Make sure the mount request we got indicates support
1008          * for this version of the protocol.
1009          */
1010         if ((minproto > 2) || (maxproto < 2))
1011                 return (EINVAL);
1012 
1013         /*
1014          * Now we need to lookup the fifos we'll be using
1015          * to talk to the userland automounter process.
1016          */
1017         if (i_fifo_lookup(pgrp, fd, &fp_wr, &fp_rd) != 0)
1018                 return (EINVAL);
1019 
1020         /* Save the mount options and fifo pointers. */
1021         data->lav_fd = fd;
1022         data->lav_pgrp = pgrp;
1023         data->lav_fifo_rd = fp_rd;
1024         data->lav_fifo_wr = fp_wr;
1025         return (0);
1026 }
1027 
1028 /*
1029  * VFS entry points
1030  */
1031 static int
1032 lx_autofs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
1033 {
1034         lx_autofs_vfs_t *data;
1035         dev_t           dev;
1036         char            name[40];
1037         int             error;
1038 
1039         if (secpolicy_fs_mount(cr, mvp, vfsp) != 0)
1040                 return (EPERM);
1041 
1042         if (mvp->v_type != VDIR)
1043                 return (ENOTDIR);
1044 
1045         if ((uap->flags & MS_OVERLAY) == 0 &&
1046             (mvp->v_count > 1 || (mvp->v_flag & VROOT)))
1047                 return (EBUSY);
1048 
1049         /* We don't support mountes in the global zone. */
1050         if (getzoneid() == GLOBAL_ZONEID)
1051                 return (EPERM);
1052 
1053         /* We don't support mounting on top of ourselves. */
1054         if (vn_matchops(mvp, lx_autofs_vn_ops))
1055                 return (EPERM);
1056 
1057         /* Allocate a vfs struct. */
1058         data = kmem_zalloc(sizeof (lx_autofs_vfs_t), KM_SLEEP);
1059 
1060         /* Parse mount options. */
1061         if ((error = i_parse_mntopt(vfsp, data)) != 0) {
1062                 kmem_free(data, sizeof (lx_autofs_vfs_t));
1063                 return (error);
1064         }
1065 
1066         /* Initialize the backing store. */
1067         i_bs_destroy(mvp, LX_AUTOFS_BS_DIR);
1068         if ((data->lav_bs_vp = i_bs_create(mvp, LX_AUTOFS_BS_DIR)) == NULL) {
1069                 kmem_free(data, sizeof (lx_autofs_vfs_t));
1070                 return (EBUSY);
1071         }
1072         data->lav_bs_name = LX_AUTOFS_BS_DIR;
1073 
1074         /* We have to hold the underlying vnode we're mounted on. */
1075         data->lav_mvp = mvp;
1076         VN_HOLD(mvp);
1077 
1078         /* Initialize vfs fields */
1079         vfsp->vfs_bsize = DEV_BSIZE;
1080         vfsp->vfs_fstype = lx_autofs_fstype;
1081         vfsp->vfs_data = data;
1082 
1083         /* Invent a dev_t (sigh) */
1084         do {
1085                 dev = makedevice(lx_autofs_major,
1086                     atomic_add_32_nv(&lx_autofs_minor, 1) & L_MAXMIN32);
1087         } while (vfs_devismounted(dev));
1088         vfsp->vfs_dev = dev;
1089         vfs_make_fsid(&vfsp->vfs_fsid, dev, lx_autofs_fstype);
1090 
1091         /* Create an id space arena for automounter requests. */
1092         (void) snprintf(name, sizeof (name), "lx_autofs_id_%d",
1093             getminor(vfsp->vfs_dev));
1094         data->lav_ids = id_space_create(name, 1, INT_MAX);
1095 
1096         /* Create hashes to keep track of automounter requests. */
1097         mutex_init(&data->lav_lock, NULL, MUTEX_DEFAULT, NULL);
1098         (void) snprintf(name, sizeof (name), "lx_autofs_path_hash_%d",
1099             getminor(vfsp->vfs_dev));
1100         data->lav_path_hash = mod_hash_create_strhash(name,
1101             LX_AUTOFS_VFS_PATH_HASH_SIZE, mod_hash_null_valdtor);
1102         (void) snprintf(name, sizeof (name), "lx_autofs_id_hash_%d",
1103             getminor(vfsp->vfs_dev));
1104         data->lav_id_hash = mod_hash_create_idhash(name,
1105             LX_AUTOFS_VFS_ID_HASH_SIZE, mod_hash_null_valdtor);
1106 
1107         /* Create a hash to keep track of vnodes. */
1108         (void) snprintf(name, sizeof (name), "lx_autofs_vn_hash_%d",
1109             getminor(vfsp->vfs_dev));
1110         data->lav_vn_hash = mod_hash_create_ptrhash(name,
1111             LX_AUTOFS_VFS_VN_HASH_SIZE, mod_hash_null_valdtor,
1112             sizeof (vnode_t));
1113 
1114         /* Create root vnode */
1115         data->lav_root = i_vn_alloc(vfsp, data->lav_bs_vp);
1116         data->lav_root->v_flag |=
1117             VROOT | VNOCACHE | VNOMAP | VNOSWAP | VNOMOUNT;
1118 
1119         return (0);
1120 }
1121 
1122 static int
1123 lx_autofs_unmount(vfs_t *vfsp, int flag, struct cred *cr)
1124 {
1125         lx_autofs_vfs_t *data;
1126 
1127         if (secpolicy_fs_unmount(cr, vfsp) != 0)
1128                 return (EPERM);
1129 
1130         /* We do not currently support forced unmounts. */
1131         if (flag & MS_FORCE)
1132                 return (ENOTSUP);
1133 
1134         /*
1135          * We should never have a reference count of less than 2: one for the
1136          * caller, one for the root vnode.
1137          */
1138         ASSERT(vfsp->vfs_count >= 2);
1139 
1140         /* If there are any outstanding vnodes, we can't unmount. */
1141         if (vfsp->vfs_count > 2)
1142                 return (EBUSY);
1143 
1144         /* Check for any remaining holds on the root vnode. */
1145         data = vfsp->vfs_data;
1146         ASSERT(data->lav_root->v_vfsp == vfsp);
1147         if (data->lav_root->v_count > 1)
1148                 return (EBUSY);
1149 
1150         /* Close the fifo to the automount process. */
1151         if (data->lav_fifo_wr != NULL)
1152                 (void) closef(data->lav_fifo_wr);
1153         if (data->lav_fifo_rd != NULL)
1154                 (void) closef(data->lav_fifo_rd);
1155 
1156         /*
1157          * We have to release our hold on our root vnode before we can
1158          * delete the backing store.  (Since the root vnode is linked
1159          * to the backing store.)
1160          */
1161         VN_RELE(data->lav_root);
1162 
1163         /* Cleanup the backing store. */
1164         i_bs_destroy(data->lav_mvp, data->lav_bs_name);
1165         VN_RELE(data->lav_mvp);
1166 
1167         /* Cleanup out remaining data structures. */
1168         mod_hash_destroy_strhash(data->lav_path_hash);
1169         mod_hash_destroy_idhash(data->lav_id_hash);
1170         mod_hash_destroy_ptrhash(data->lav_vn_hash);
1171         id_space_destroy(data->lav_ids);
1172         kmem_free(data, sizeof (lx_autofs_vfs_t));
1173 
1174         return (0);
1175 }
1176 
1177 static int
1178 lx_autofs_root(vfs_t *vfsp, vnode_t **vpp)
1179 {
1180         lx_autofs_vfs_t *data = vfsp->vfs_data;
1181 
1182         *vpp = data->lav_root;
1183         VN_HOLD(*vpp);
1184 
1185         return (0);
1186 }
1187 
1188 static int
1189 lx_autofs_statvfs(vfs_t *vfsp, statvfs64_t *sp)
1190 {
1191         lx_autofs_vfs_t *data = vfsp->vfs_data;
1192         vnode_t         *urvp = data->lav_root->v_data;
1193         dev32_t         d32;
1194         int             error;
1195 
1196         if ((error = VFS_STATVFS(urvp->v_vfsp, sp)) != 0)
1197                 return (error);
1198 
1199         /* Update some of values before returning. */
1200         (void) cmpldev(&d32, vfsp->vfs_dev);
1201         sp->f_fsid = d32;
1202         (void) strlcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name,
1203             sizeof (sp->f_basetype));
1204         sp->f_flag = vf_to_stf(vfsp->vfs_flag);
1205         bzero(sp->f_fstr, sizeof (sp->f_fstr));
1206         return (0);
1207 }
1208 
1209 static const fs_operation_def_t lx_autofs_vfstops[] = {
1210         { VFSNAME_MOUNT,        { .vfs_mount = lx_autofs_mount } },
1211         { VFSNAME_UNMOUNT,      { .vfs_unmount = lx_autofs_unmount } },
1212         { VFSNAME_ROOT,         { .vfs_root = lx_autofs_root } },
1213         { VFSNAME_STATVFS,      { .vfs_statvfs = lx_autofs_statvfs } },
1214         { NULL, NULL }
1215 };
1216 
1217 /*
1218  * VOP entry points - simple passthrough
1219  *
1220  * For most VOP entry points we can simply pass the request on to
1221  * the underlying filesystem we're mounted on.
1222  */
1223 static int
1224 lx_autofs_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
1225     caller_context_t *ctp)
1226 {
1227         vnode_t *uvp = vp->v_data;
1228         return (VOP_CLOSE(uvp, flag, count, offset, cr, ctp));
1229 }
1230 
1231 static int
1232 lx_autofs_readdir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
1233     caller_context_t *ctp, int flags)
1234 {
1235         vnode_t *uvp = vp->v_data;
1236         return (VOP_READDIR(uvp, uiop, cr, eofp, ctp, flags));
1237 }
1238 
1239 static int
1240 lx_autofs_access(vnode_t *vp, int mode, int flags, cred_t *cr,
1241     caller_context_t *ctp)
1242 {
1243         vnode_t *uvp = vp->v_data;
1244         return (VOP_ACCESS(uvp, mode, flags, cr, ctp));
1245 }
1246 
1247 static int
1248 lx_autofs_rwlock(struct vnode *vp, int write_lock, caller_context_t *ctp)
1249 {
1250         vnode_t *uvp = vp->v_data;
1251         return (VOP_RWLOCK(uvp, write_lock, ctp));
1252 }
1253 
1254 static void
1255 lx_autofs_rwunlock(struct vnode *vp, int write_lock, caller_context_t *ctp)
1256 {
1257         vnode_t *uvp = vp->v_data;
1258         VOP_RWUNLOCK(uvp, write_lock, ctp);
1259 }
1260 
1261 /*ARGSUSED*/
1262 static int
1263 lx_autofs_rmdir(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cr,
1264     caller_context_t *ctp, int flags)
1265 {
1266         vnode_t *udvp = dvp->v_data;
1267 
1268         /*
1269          * cdir is the calling processes current directory.
1270          * If cdir is lx_autofs vnode then get its real underlying
1271          * vnode ptr.  (It seems like the only thing cdir is
1272          * ever used for is to make sure the user doesn't delete
1273          * their current directory.)
1274          */
1275         if (vn_matchops(cdir, lx_autofs_vn_ops)) {
1276                 vnode_t *ucdir = cdir->v_data;
1277                 return (VOP_RMDIR(udvp, nm, ucdir, cr, ctp, flags));
1278         }
1279 
1280         return (VOP_RMDIR(udvp, nm, cdir, cr, ctp, flags));
1281 }
1282 
1283 /*
1284  * VOP entry points - special passthrough
1285  *
1286  * For some VOP entry points we will first pass the request on to
1287  * the underlying filesystem we're mounted on.  If there's an error
1288  * then we immediately return the error, but if the request succeeds
1289  * we have to do some extra work before returning.
1290  */
1291 static int
1292 lx_autofs_open(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ctp)
1293 {
1294         vnode_t         *ovp = *vpp;
1295         vnode_t         *uvp = ovp->v_data;
1296         int             error;
1297 
1298         if ((error = VOP_OPEN(&uvp, flag, cr, ctp)) != 0)
1299                 return (error);
1300 
1301         /* Check for clone opens. */
1302         if (uvp == ovp->v_data)
1303                 return (0);
1304 
1305         /* Deal with clone opens by returning a new vnode. */
1306         *vpp = i_vn_alloc(ovp->v_vfsp, uvp);
1307         VN_RELE(ovp);
1308         return (0);
1309 }
1310 
1311 static int
1312 lx_autofs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
1313     caller_context_t *ctp)
1314 {
1315         vnode_t         *uvp = vp->v_data;
1316         int             error;
1317 
1318         if ((error = VOP_GETATTR(uvp, vap, flags, cr, ctp)) != 0)
1319                 return (error);
1320 
1321         /* Update the attributes with our filesystem id. */
1322         vap->va_fsid = vp->v_vfsp->vfs_dev;
1323         return (0);
1324 }
1325 
1326 static int
1327 lx_autofs_mkdir(vnode_t *dvp, char *nm, struct vattr *vap, vnode_t **vpp,
1328     cred_t *cr, caller_context_t *ctp, int flags, vsecattr_t *vsecp)
1329 {
1330         vnode_t         *udvp = dvp->v_data;
1331         vnode_t         *uvp = NULL;
1332         int             error;
1333 
1334         if ((error = VOP_MKDIR(udvp, nm, vap, &uvp, cr,
1335             ctp, flags, vsecp)) != 0)
1336                 return (error);
1337 
1338         /* Update the attributes with our filesystem id. */
1339         vap->va_fsid = dvp->v_vfsp->vfs_dev;
1340 
1341         /* Allocate a new vnode. */
1342         *vpp = i_vn_alloc(dvp->v_vfsp, uvp);
1343         return (0);
1344 }
1345 
1346 /*
1347  * VOP entry points - custom
1348  */
1349 /*ARGSUSED*/
1350 static void
1351 lx_autofs_inactive(struct vnode *vp, struct cred *cr, caller_context_t *ctp)
1352 {
1353         lx_autofs_vfs_t *data = vp->v_vfsp->vfs_data;
1354 
1355         /*
1356          * We need to hold the vfs lock because if we're going to free
1357          * this vnode we have to prevent anyone from looking it up
1358          * in the vnode hash.
1359          */
1360         mutex_enter(&data->lav_lock);
1361         mutex_enter(&vp->v_lock);
1362 
1363         if (vp->v_count < 1) {
1364                 panic("lx_autofs_inactive: bad v_count");
1365                 /*NOTREACHED*/
1366         }
1367 
1368         /* Drop the temporary hold by vn_rele now. */
1369         if (--vp->v_count > 0) {
1370                 mutex_exit(&vp->v_lock);
1371                 mutex_exit(&data->lav_lock);
1372                 return;
1373         }
1374 
1375         /*
1376          * No one should have been blocked on this lock because we're
1377          * about to free this vnode.
1378          */
1379         i_vn_free(vp);
1380 }
1381 
1382 static int
1383 lx_autofs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
1384     int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ctp,
1385     int *direntflags, pathname_t *realpnp)
1386 {
1387         vnode_t                 *udvp = dvp->v_data;
1388         vnode_t                 *uvp = NULL;
1389         int                     error;
1390 
1391         /* First try to lookup if this path component already exitst. */
1392         if ((error = VOP_LOOKUP(udvp, nm, &uvp, pnp, flags, rdir, cr, ctp,
1393             direntflags, realpnp)) == 0) {
1394                 *vpp = i_vn_alloc(dvp->v_vfsp, uvp);
1395                 return (0);
1396         }
1397 
1398         /* Only query the automounter if the path does not exist. */
1399         if (error != ENOENT)
1400                 return (error);
1401 
1402         /* Refer the lookup to the automounter. */
1403         if ((error = i_automounter_call(dvp, nm)) != 0)
1404                 return (error);
1405 
1406         /* Retry the lookup operation. */
1407         if ((error = VOP_LOOKUP(udvp, nm, &uvp, pnp, flags, rdir, cr, ctp,
1408             direntflags, realpnp)) == 0) {
1409                 *vpp = i_vn_alloc(dvp->v_vfsp, uvp);
1410                 return (0);
1411         }
1412         return (error);
1413 }
1414 
1415 /*ARGSUSED*/
1416 static int
1417 lx_autofs_ioctl(vnode_t *vp, int cmd, intptr_t arg, int mode, cred_t *cr,
1418     int *rvalp, caller_context_t *ctp)
1419 {
1420         vnode_t                 *uvp = vp->v_data;
1421 
1422         /* Intercept certain ioctls. */
1423         switch ((uint_t)cmd) {
1424         case LX_AUTOFS_IOC_READY:
1425         case LX_AUTOFS_IOC_FAIL:
1426         case LX_AUTOFS_IOC_CATATONIC:
1427         case LX_AUTOFS_IOC_EXPIRE:
1428         case LX_AUTOFS_IOC_PROTOVER:
1429         case LX_AUTOFS_IOC_SETTIMEOUT:
1430                 return (i_automounter_ioctl(vp, cmd, arg));
1431         }
1432 
1433         /* Pass any remaining ioctl on. */
1434         return (VOP_IOCTL(uvp, cmd, arg, mode, cr, rvalp, ctp));
1435 }
1436 
1437 /*
1438  * VOP entry points definitions
1439  */
1440 static const fs_operation_def_t lx_autofs_tops_root[] = {
1441         { VOPNAME_OPEN,         { .vop_open = lx_autofs_open } },
1442         { VOPNAME_CLOSE,        { .vop_close = lx_autofs_close } },
1443         { VOPNAME_IOCTL,        { .vop_ioctl = lx_autofs_ioctl } },
1444         { VOPNAME_RWLOCK,       { .vop_rwlock = lx_autofs_rwlock } },
1445         { VOPNAME_RWUNLOCK,     { .vop_rwunlock = lx_autofs_rwunlock } },
1446         { VOPNAME_GETATTR,      { .vop_getattr = lx_autofs_getattr } },
1447         { VOPNAME_ACCESS,       { .vop_access = lx_autofs_access } },
1448         { VOPNAME_READDIR,      { .vop_readdir = lx_autofs_readdir } },
1449         { VOPNAME_LOOKUP,       { .vop_lookup = lx_autofs_lookup } },
1450         { VOPNAME_INACTIVE,     { .vop_inactive = lx_autofs_inactive } },
1451         { VOPNAME_MKDIR,        { .vop_mkdir = lx_autofs_mkdir } },
1452         { VOPNAME_RMDIR,        { .vop_rmdir = lx_autofs_rmdir } },
1453         { NULL }
1454 };
1455 
1456 /*
1457  * lx_autofs_init() gets invoked via the mod_install() call in
1458  * this modules _init() routine.  Therefor, the code that cleans
1459  * up the structures we allocate below is actually found in
1460  * our _fini() routine.
1461  */
1462 /* ARGSUSED */
1463 static int
1464 lx_autofs_init(int fstype, char *name)
1465 {
1466         int             error;
1467 
1468         if ((lx_autofs_major =
1469             (major_t)space_fetch(LX_AUTOFS_SPACE_KEY_UDEV)) == 0) {
1470 
1471                 if ((lx_autofs_major = getudev()) == (major_t)-1) {
1472                         cmn_err(CE_WARN, "lx_autofs_init: "
1473                             "can't get unique device number");
1474                         return (EAGAIN);
1475                 }
1476 
1477                 if (space_store(LX_AUTOFS_SPACE_KEY_UDEV,
1478                     (uintptr_t)lx_autofs_major) != 0) {
1479                         cmn_err(CE_WARN, "lx_autofs_init: "
1480                             "can't save unique device number");
1481                         return (EAGAIN);
1482                 }
1483         }
1484 
1485         lx_autofs_fstype = fstype;
1486         if ((error = vfs_setfsops(
1487             fstype, lx_autofs_vfstops, &lx_autofs_vfsops)) != 0) {
1488                 cmn_err(CE_WARN, "lx_autofs_init: bad vfs ops template");
1489                 return (error);
1490         }
1491 
1492         if ((error = vn_make_ops("lx_autofs vnode ops",
1493             lx_autofs_tops_root, &lx_autofs_vn_ops)) != 0) {
1494                 VERIFY(vfs_freevfsops_by_type(fstype) == 0);
1495                 lx_autofs_vn_ops = NULL;
1496                 return (error);
1497         }
1498 
1499         return (0);
1500 }
1501 
1502 
1503 /*
1504  * Module linkage
1505  */
1506 static mntopt_t lx_autofs_mntopt[] = {
1507         { LX_MNTOPT_FD,         NULL,   0,      MO_HASVALUE },
1508         { LX_MNTOPT_PGRP,       NULL,   0,      MO_HASVALUE },
1509         { LX_MNTOPT_MINPROTO,   NULL,   0,      MO_HASVALUE },
1510         { LX_MNTOPT_MAXPROTO,   NULL,   0,      MO_HASVALUE }
1511 };
1512 
1513 static mntopts_t lx_autofs_mntopts = {
1514         sizeof (lx_autofs_mntopt) / sizeof (mntopt_t),
1515         lx_autofs_mntopt
1516 };
1517 
1518 static vfsdef_t vfw = {
1519         VFSDEF_VERSION,
1520         LX_AUTOFS_NAME,
1521         lx_autofs_init,
1522         VSW_HASPROTO | VSW_VOLATILEDEV,
1523         &lx_autofs_mntopts
1524 };
1525 
1526 extern struct mod_ops mod_fsops;
1527 
1528 static struct modlfs modlfs = {
1529         &mod_fsops, "linux autofs filesystem", &vfw
1530 };
1531 
1532 static struct modlinkage modlinkage = {
1533         MODREV_1, (void *)&modlfs, NULL
1534 };
1535 
1536 int
1537 _init(void)
1538 {
1539         return (mod_install(&modlinkage));
1540 }
1541 
1542 int
1543 _info(struct modinfo *modinfop)
1544 {
1545         return (mod_info(&modlinkage, modinfop));
1546 }
1547 
1548 int
1549 _fini(void)
1550 {
1551         int             error;
1552 
1553         if ((error = mod_remove(&modlinkage)) != 0)
1554                 return (error);
1555 
1556         if (lx_autofs_vn_ops != NULL) {
1557                 vn_freevnodeops(lx_autofs_vn_ops);
1558                 lx_autofs_vn_ops = NULL;
1559         }
1560 
1561         /*
1562          * In our init routine, if we get an error after calling
1563          * vfs_setfsops() we cleanup by calling vfs_freevfsops_by_type().
1564          * But we don't need to call vfs_freevfsops_by_type() here
1565          * because the fs framework did this for us as part of the
1566          * mod_remove() call above.
1567          */
1568         return (0);
1569 }