Print this page
PSARC 2008/290 lofi mount
6384817 Need persistent lofi based mounts and direct mount(1m) support for lofi

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/ufs/ufs_vfsops.c
          +++ new/usr/src/uts/common/fs/ufs/ufs_vfsops.c
↓ open down ↓ 11 lines elided ↑ open up ↑
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22      - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
       22 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  
  26   26  /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T     */
  27   27  /*        All Rights Reserved   */
  28   28  
  29   29  /*
  30   30   * University Copyright- Copyright (c) 1982, 1986, 1988
  31   31   * The Regents of the University of California
  32   32   * All Rights Reserved
  33   33   *
  34   34   * University Acknowledgment- Portions of this document are derived from
  35   35   * software developed by the University of California, Berkeley, and its
  36   36   * contributors.
  37   37   */
  38   38  
  39   39  
  40      -#pragma ident   "@(#)ufs_vfsops.c       2.275   07/10/25 SMI"
       40 +#pragma ident   "@(#)ufs_vfsops.c       2.276   08/05/07 SMI"
  41   41  
  42   42  #include <sys/types.h>
  43   43  #include <sys/t_lock.h>
  44   44  #include <sys/param.h>
  45   45  #include <sys/systm.h>
  46   46  #include <sys/bitmap.h>
  47   47  #include <sys/sysmacros.h>
  48   48  #include <sys/kmem.h>
  49   49  #include <sys/signal.h>
  50   50  #include <sys/user.h>
↓ open down ↓ 208 lines elided ↑ open up ↑
 259  259  
 260  260  static int
 261  261  ufs_mount(struct vfs *vfsp, struct vnode *mvp, struct mounta *uap,
 262  262          struct cred *cr)
 263  263  
 264  264  {
 265  265          char *data = uap->dataptr;
 266  266          int datalen = uap->datalen;
 267  267          dev_t dev;
 268  268          struct vnode *bvp;
      269 +        struct vnode *lvp = NULL;
      270 +        struct vnode *svp = NULL;
 269  271          struct pathname dpn;
 270  272          int error;
 271  273          enum whymountroot why = ROOT_INIT;
 272  274          struct ufs_args args;
 273  275          int oflag, aflag;
 274  276          int fromspace = (uap->flags & MS_SYSSPACE) ?
 275  277              UIO_SYSSPACE : UIO_USERSPACE;
 276  278  
 277  279          if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0)
 278  280                  return (error);
↓ open down ↓ 22 lines elided ↑ open up ↑
 301  303                  if (uap->flags & MS_SYSSPACE)
 302  304                          bcopy(data, &args, datalen);
 303  305                  else
 304  306                          copy_result = copyin(data, &args, datalen);
 305  307                  if (copy_result)
 306  308                          return (EFAULT);
 307  309                  datalen = sizeof (struct ufs_args);
 308  310          } else {
 309  311                  datalen = 0;
 310  312          }
      313 +
      314 +        if ((vfsp->vfs_flag & VFS_RDONLY) != 0 ||
      315 +            (uap->flags & MS_RDONLY) != 0) {
      316 +                oflag = FREAD;
      317 +                aflag = VREAD;
      318 +        } else {
      319 +                oflag = FREAD | FWRITE;
      320 +                aflag = VREAD | VWRITE;
      321 +        }
      322 +
 311  323          /*
 312  324           * Read in the mount point pathname
 313  325           * (so we can record the directory the file system was last mounted on).
 314  326           */
 315  327          if (error = pn_get(uap->dir, fromspace, &dpn))
 316  328                  return (error);
 317  329  
 318  330          /*
 319  331           * Resolve path name of special file being mounted.
 320  332           */
 321      -        if (error = lookupname(uap->spec, fromspace, FOLLOW, NULL, &bvp)) {
      333 +        if (error = lookupname(uap->spec, fromspace, FOLLOW, NULL, &svp)) {
 322  334                  pn_free(&dpn);
 323  335                  return (error);
 324  336          }
 325      -        if (bvp->v_type != VBLK) {
 326      -                VN_RELE(bvp);
      337 +
      338 +        error = vfs_get_lofi(vfsp, &lvp);
      339 +
      340 +        if (error > 0) {
      341 +                VN_RELE(svp);
 327  342                  pn_free(&dpn);
 328      -                return (ENOTBLK);
      343 +                return (error);
      344 +        } else if (error == 0) {
      345 +                bvp = lvp;
      346 +        } else {
      347 +                bvp = svp;
      348 +
      349 +                if (svp->v_type != VBLK) {
      350 +                        VN_RELE(svp);
      351 +                        pn_free(&dpn);
      352 +                        return (ENOTBLK);
      353 +                }
      354 +
      355 +                if ((error = secpolicy_spec_open(cr, svp, oflag)) != 0) {
      356 +                        VN_RELE(svp);
      357 +                        pn_free(&dpn);
      358 +                        return (error);
      359 +                }
 329  360          }
      361 +
 330  362          dev = bvp->v_rdev;
 331  363          if (getmajor(dev) >= devcnt) {
 332  364                  pn_free(&dpn);
 333      -                VN_RELE(bvp);
      365 +                if (lvp != NULL)
      366 +                        VN_RELE(lvp);
      367 +                if (svp != NULL)
      368 +                        VN_RELE(svp);
 334  369                  return (ENXIO);
 335  370          }
 336  371          if (uap->flags & MS_REMOUNT)
 337  372                  why = ROOT_REMOUNT;
 338  373  
 339  374          /*
 340      -         * In SunCluster, requests to a global device are satisfied by
 341      -         * a local device. We substitute the global pxfs node with a
 342      -         * local spec node here.
      375 +         * In SunCluster, requests to a global device are satisfied by a
      376 +         * local device. We substitute the global pxfs node with a local
      377 +         * spec node here.
      378 +         *
      379 +         * Open device/file mounted on.  We need this to check whether
      380 +         * the caller has sufficient rights to access the resource in
      381 +         * question.  When bio is fixed for vnodes this can all be vnode
      382 +         * operations.
 343  383           */
 344  384          if (IS_PXFSVP(bvp)) {
 345      -                VN_RELE(bvp);
      385 +                ASSERT(lvp == NULL);
      386 +                VN_RELE(svp);
      387 +                svp = NULL;
 346  388                  bvp = makespecvp(dev, VBLK);
 347      -        }
 348      -
 349      -        /*
 350      -         * Open block device mounted on.  We need this to
 351      -         * check whether the caller has sufficient rights to
 352      -         * access the device in question.
 353      -         * When bio is fixed for vnodes this can all be vnode
 354      -         * operations.
 355      -         */
 356      -        if ((vfsp->vfs_flag & VFS_RDONLY) != 0 ||
 357      -            (uap->flags & MS_RDONLY) != 0) {
 358      -                oflag = FREAD;
 359      -                aflag = VREAD;
      389 +                error = VOP_ACCESS(bvp, aflag, 0, cr, NULL);
 360  390          } else {
 361      -                oflag = FREAD | FWRITE;
 362      -                aflag = VREAD | VWRITE;
      391 +                error = VOP_ACCESS(svp, aflag, 0, cr, NULL);
 363  392          }
 364      -        if ((error = VOP_ACCESS(bvp, aflag, 0, cr, NULL)) != 0 ||
 365      -            (error = secpolicy_spec_open(cr, bvp, oflag)) != 0) {
      393 +
      394 +        if (error != 0) {
 366  395                  pn_free(&dpn);
 367      -                VN_RELE(bvp);
      396 +                if (lvp != NULL)
      397 +                        VN_RELE(lvp);
      398 +                if (svp != NULL)
      399 +                        VN_RELE(svp);
 368  400                  return (error);
 369  401          }
 370  402  
 371  403          /*
 372  404           * Ensure that this device isn't already mounted or in progress on a
 373  405           * mount unless this is a REMOUNT request or we are told to suppress
 374  406           * mount checks. Global mounts require special handling.
 375  407           */
 376  408          if ((uap->flags & MS_NOCHECK) == 0) {
 377  409                  if ((uap->flags & MS_GLOBAL) == 0 &&
 378  410                      vfs_devmounting(dev, vfsp)) {
 379  411                          pn_free(&dpn);
 380      -                        VN_RELE(bvp);
      412 +                        if (lvp != NULL)
      413 +                                VN_RELE(lvp);
      414 +                        if (svp != NULL)
      415 +                                VN_RELE(svp);
 381  416                          return (EBUSY);
 382  417                  }
 383  418                  if (vfs_devismounted(dev)) {
 384  419                          if ((uap->flags & MS_REMOUNT) == 0) {
 385  420                                  pn_free(&dpn);
 386      -                                VN_RELE(bvp);
      421 +                                if (lvp != NULL)
      422 +                                        VN_RELE(lvp);
      423 +                                if (svp != NULL)
      424 +                                        VN_RELE(svp);
 387  425                                  return (EBUSY);
 388  426                          }
 389  427                  }
 390  428          }
 391  429  
 392  430          /*
 393  431           * If the device is a tape, mount it read only
 394  432           */
 395  433          if (devopsp[getmajor(dev)]->devo_cb_ops->cb_flag & D_TAPE) {
 396  434                  vfsp->vfs_flag |= VFS_RDONLY;
 397  435                  vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0);
 398  436          }
 399  437          if (uap->flags & MS_RDONLY)
 400  438                  vfsp->vfs_flag |= VFS_RDONLY;
 401  439  
 402  440          /*
 403  441           * Mount the filesystem, free the device vnode on error.
 404  442           */
 405  443          error = mountfs(vfsp, why, bvp, dpn.pn_path, cr, 0, &args, datalen);
 406  444          pn_free(&dpn);
      445 +
 407  446          if (error) {
 408      -                VN_RELE(bvp);
      447 +                if (lvp != NULL)
      448 +                        VN_RELE(lvp);
      449 +                if (svp != NULL)
      450 +                        VN_RELE(svp);
      451 +        } else {
      452 +                /*
      453 +                 * If lofi, drop our reference to the original file.
      454 +                 */
      455 +                if (lvp != NULL)
      456 +                        VN_RELE(svp);
 409  457          }
      458 +
 410  459          if (error == 0)
 411  460                  vfs_set_feature(vfsp, VFSFT_XVATTR);
 412  461          return (error);
 413  462  }
 414  463  /*
 415  464   * Mount root file system.
 416  465   * "why" is ROOT_INIT on initial call ROOT_REMOUNT if called to
 417  466   * remount the root file system, and ROOT_UNMOUNT if called to
 418  467   * unmount the root (e.g., as part of a system shutdown).
 419  468   *
↓ open down ↓ 1844 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX