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

*** 17,27 **** * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* ! * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ --- 17,27 ---- * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* ! * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */
*** 35,45 **** * software developed by the University of California, Berkeley, and its * contributors. */ ! #pragma ident "@(#)ufs_vfsops.c 2.275 07/10/25 SMI" #include <sys/types.h> #include <sys/t_lock.h> #include <sys/param.h> #include <sys/systm.h> --- 35,45 ---- * software developed by the University of California, Berkeley, and its * contributors. */ ! #pragma ident "@(#)ufs_vfsops.c 2.276 08/05/07 SMI" #include <sys/types.h> #include <sys/t_lock.h> #include <sys/param.h> #include <sys/systm.h>
*** 264,273 **** --- 264,275 ---- { char *data = uap->dataptr; int datalen = uap->datalen; dev_t dev; struct vnode *bvp; + struct vnode *lvp = NULL; + struct vnode *svp = NULL; struct pathname dpn; int error; enum whymountroot why = ROOT_INIT; struct ufs_args args; int oflag, aflag;
*** 306,315 **** --- 308,327 ---- return (EFAULT); datalen = sizeof (struct ufs_args); } else { datalen = 0; } + + if ((vfsp->vfs_flag & VFS_RDONLY) != 0 || + (uap->flags & MS_RDONLY) != 0) { + oflag = FREAD; + aflag = VREAD; + } else { + oflag = FREAD | FWRITE; + aflag = VREAD | VWRITE; + } + /* * Read in the mount point pathname * (so we can record the directory the file system was last mounted on). */ if (error = pn_get(uap->dir, fromspace, &dpn))
*** 316,372 **** return (error); /* * Resolve path name of special file being mounted. */ ! if (error = lookupname(uap->spec, fromspace, FOLLOW, NULL, &bvp)) { pn_free(&dpn); return (error); } ! if (bvp->v_type != VBLK) { ! VN_RELE(bvp); pn_free(&dpn); return (ENOTBLK); } dev = bvp->v_rdev; if (getmajor(dev) >= devcnt) { pn_free(&dpn); ! VN_RELE(bvp); return (ENXIO); } if (uap->flags & MS_REMOUNT) why = ROOT_REMOUNT; /* ! * In SunCluster, requests to a global device are satisfied by ! * a local device. We substitute the global pxfs node with a ! * local spec node here. */ if (IS_PXFSVP(bvp)) { ! VN_RELE(bvp); bvp = makespecvp(dev, VBLK); ! } ! ! /* ! * Open block device mounted on. We need this to ! * check whether the caller has sufficient rights to ! * access the device in question. ! * When bio is fixed for vnodes this can all be vnode ! * operations. ! */ ! if ((vfsp->vfs_flag & VFS_RDONLY) != 0 || ! (uap->flags & MS_RDONLY) != 0) { ! oflag = FREAD; ! aflag = VREAD; } else { ! oflag = FREAD | FWRITE; ! aflag = VREAD | VWRITE; } ! if ((error = VOP_ACCESS(bvp, aflag, 0, cr, NULL)) != 0 || ! (error = secpolicy_spec_open(cr, bvp, oflag)) != 0) { pn_free(&dpn); ! VN_RELE(bvp); return (error); } /* * Ensure that this device isn't already mounted or in progress on a --- 328,404 ---- return (error); /* * Resolve path name of special file being mounted. */ ! if (error = lookupname(uap->spec, fromspace, FOLLOW, NULL, &svp)) { pn_free(&dpn); return (error); } ! ! error = vfs_get_lofi(vfsp, &lvp); ! ! if (error > 0) { ! VN_RELE(svp); pn_free(&dpn); + return (error); + } else if (error == 0) { + bvp = lvp; + } else { + bvp = svp; + + if (svp->v_type != VBLK) { + VN_RELE(svp); + pn_free(&dpn); return (ENOTBLK); } + + if ((error = secpolicy_spec_open(cr, svp, oflag)) != 0) { + VN_RELE(svp); + pn_free(&dpn); + return (error); + } + } + dev = bvp->v_rdev; if (getmajor(dev) >= devcnt) { pn_free(&dpn); ! if (lvp != NULL) ! VN_RELE(lvp); ! if (svp != NULL) ! VN_RELE(svp); return (ENXIO); } if (uap->flags & MS_REMOUNT) why = ROOT_REMOUNT; /* ! * In SunCluster, requests to a global device are satisfied by a ! * local device. We substitute the global pxfs node with a local ! * spec node here. ! * ! * Open device/file mounted on. We need this to check whether ! * the caller has sufficient rights to access the resource in ! * question. When bio is fixed for vnodes this can all be vnode ! * operations. */ if (IS_PXFSVP(bvp)) { ! ASSERT(lvp == NULL); ! VN_RELE(svp); ! svp = NULL; bvp = makespecvp(dev, VBLK); ! error = VOP_ACCESS(bvp, aflag, 0, cr, NULL); } else { ! error = VOP_ACCESS(svp, aflag, 0, cr, NULL); } ! ! if (error != 0) { pn_free(&dpn); ! if (lvp != NULL) ! VN_RELE(lvp); ! if (svp != NULL) ! VN_RELE(svp); return (error); } /* * Ensure that this device isn't already mounted or in progress on a
*** 375,391 **** */ if ((uap->flags & MS_NOCHECK) == 0) { if ((uap->flags & MS_GLOBAL) == 0 && vfs_devmounting(dev, vfsp)) { pn_free(&dpn); ! VN_RELE(bvp); return (EBUSY); } if (vfs_devismounted(dev)) { if ((uap->flags & MS_REMOUNT) == 0) { pn_free(&dpn); ! VN_RELE(bvp); return (EBUSY); } } } --- 407,429 ---- */ if ((uap->flags & MS_NOCHECK) == 0) { if ((uap->flags & MS_GLOBAL) == 0 && vfs_devmounting(dev, vfsp)) { pn_free(&dpn); ! if (lvp != NULL) ! VN_RELE(lvp); ! if (svp != NULL) ! VN_RELE(svp); return (EBUSY); } if (vfs_devismounted(dev)) { if ((uap->flags & MS_REMOUNT) == 0) { pn_free(&dpn); ! if (lvp != NULL) ! VN_RELE(lvp); ! if (svp != NULL) ! VN_RELE(svp); return (EBUSY); } } }
*** 402,414 **** /* * Mount the filesystem, free the device vnode on error. */ error = mountfs(vfsp, why, bvp, dpn.pn_path, cr, 0, &args, datalen); pn_free(&dpn); if (error) { ! VN_RELE(bvp); } if (error == 0) vfs_set_feature(vfsp, VFSFT_XVATTR); return (error); } /* --- 440,463 ---- /* * Mount the filesystem, free the device vnode on error. */ error = mountfs(vfsp, why, bvp, dpn.pn_path, cr, 0, &args, datalen); pn_free(&dpn); + if (error) { ! if (lvp != NULL) ! VN_RELE(lvp); ! if (svp != NULL) ! VN_RELE(svp); ! } else { ! /* ! * If lofi, drop our reference to the original file. ! */ ! if (lvp != NULL) ! VN_RELE(svp); } + if (error == 0) vfs_set_feature(vfsp, VFSFT_XVATTR); return (error); } /*