Print this page
PSARC 2008/290 lofi mount
6384817 Need persistent lofi based mounts and direct mount(1m) support for lofi
@@ -17,15 +17,15 @@
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "@(#)hsfs_vfsops.c 1.97 07/10/25 SMI"
+#pragma ident "@(#)hsfs_vfsops.c 1.98 08/05/07 SMI"
/*
* VFS operations for High Sierra filesystem
*/
@@ -1341,60 +1341,86 @@
static int
hs_getmdev(struct vfs *vfsp, char *fspec, int flags, dev_t *pdev, mode_t *mode,
cred_t *cr)
{
int error;
- struct vnode *vp;
+ struct vnode *svp = NULL;
+ struct vnode *lvp = NULL;
+ struct vnode *bvp;
struct vattr vap;
dev_t dev;
+ enum uio_seg fromspace = (flags & MS_SYSSPACE) ?
+ UIO_SYSSPACE : UIO_USERSPACE;
/*
- * Get the device to be mounted
+ * Look up the device/file to be mounted.
*/
- error = lookupname(fspec, (flags & MS_SYSSPACE) ?
- UIO_SYSSPACE : UIO_USERSPACE, FOLLOW, NULLVPP, &vp);
+ error = lookupname(fspec, fromspace, FOLLOW, NULLVPP, &svp);
if (error) {
- if (error == ENOENT) {
- return (ENODEV); /* needs translation */
+ if (error == ENOENT)
+ error = ENODEV;
+ goto out;
}
- return (error);
+
+ error = vfs_get_lofi(vfsp, &lvp);
+
+ if (error > 0) {
+ if (error == ENOENT)
+ error = ENODEV;
+ goto out;
+ } else if (error == 0) {
+ bvp = lvp;
+ } else {
+ bvp = svp;
+
+ if (bvp->v_type != VBLK) {
+ error = ENOTBLK;
+ goto out;
}
- if (vp->v_type != VBLK) {
- VN_RELE(vp);
- return (ENOTBLK);
+
+ if ((error = secpolicy_spec_open(cr, bvp, FREAD)) != 0)
+ goto out;
}
+
/*
- * Can we read from the device?
+ * Can we read from the device/file ?
*/
- if ((error = VOP_ACCESS(vp, VREAD, 0, cr, NULL)) != 0 ||
- (error = secpolicy_spec_open(cr, vp, FREAD)) != 0) {
- VN_RELE(vp);
- return (error);
- }
+ if ((error = VOP_ACCESS(svp, VREAD, 0, cr, NULL)) != 0)
+ goto out;
vap.va_mask = AT_MODE; /* get protection mode */
- (void) VOP_GETATTR(vp, &vap, 0, CRED(), NULL);
+ (void) VOP_GETATTR(bvp, &vap, 0, CRED(), NULL);
*mode = vap.va_mode;
- dev = *pdev = vp->v_rdev;
- VN_RELE(vp);
+ dev = *pdev = bvp->v_rdev;
+ error = EBUSY;
+
/*
* Ensure that this device isn't already mounted,
* unless this is a REMOUNT request or we are told to suppress
* mount checks.
*/
if ((flags & MS_NOCHECK) == 0) {
if (vfs_devmounting(dev, vfsp))
- return (EBUSY);
+ goto out;
if (vfs_devismounted(dev) && !(flags & MS_REMOUNT))
- return (EBUSY);
+ goto out;
}
- if (getmajor(*pdev) >= devcnt)
- return (ENXIO);
- return (0);
+ if (getmajor(*pdev) >= devcnt) {
+ error = ENXIO;
+ goto out;
+ }
+
+ error = 0;
+out:
+ if (svp != NULL)
+ VN_RELE(svp);
+ if (lvp != NULL)
+ VN_RELE(lvp);
+ return (error);
}
static void
hs_copylabel(struct hs_volume *hvp, unsigned char *label, int isjoliet)
{