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 "@(#)pc_vfsops.c 1.104 07/10/25 SMI"
+#pragma ident "@(#)pc_vfsops.c 1.105 08/05/07 SMI"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kmem.h>
#include <sys/user.h>
@@ -291,11 +291,12 @@
int *dos_ldrive,
dev_t *xdev)
{
struct pathname special;
char *c;
- struct vnode *bvp;
+ struct vnode *svp = NULL;
+ struct vnode *lvp = NULL;
int oflag, aflag;
int error;
/*
* Resolve path name of special file being mounted.
@@ -305,11 +306,11 @@
}
*dos_ldrive = -1;
if (error =
- lookupname(special.pn_path, UIO_SYSSPACE, FOLLOW, NULLVPP, &bvp)) {
+ lookupname(special.pn_path, UIO_SYSSPACE, FOLLOW, NULLVPP, &svp)) {
/*
* If there's no device node, the name specified most likely
* maps to a PCFS-style "partition specifier" to select a
* harddisk primary/logical partition. Disable floppy-specific
* checks in such cases unless an explicit :A or :B is
@@ -382,11 +383,11 @@
goto devlookup_done;
}
error = lookupname(special.pn_path, UIO_SYSSPACE, FOLLOW,
- NULLVPP, &bvp);
+ NULLVPP, &svp);
} else {
*dos_ldrive = UNPARTITIONED_DRIVE;
}
devlookup_done:
pn_free(&special);
@@ -393,12 +394,10 @@
if (error)
return (error);
ASSERT(*dos_ldrive >= UNPARTITIONED_DRIVE);
- *xdev = bvp->v_rdev;
-
/*
* Verify caller's permission to open the device special file.
*/
if ((vfsp->vfs_flag & VFS_RDONLY) != 0 ||
((uap->flags & MS_RDONLY) != 0)) {
@@ -407,24 +406,42 @@
} else {
oflag = FREAD | FWRITE;
aflag = VREAD | VWRITE;
}
- if (bvp->v_type != VBLK)
+ error = vfs_get_lofi(vfsp, &lvp);
+
+ if (error > 0) {
+ if (error == ENOENT)
+ error = ENODEV;
+ goto out;
+ } else if (error == 0) {
+ *xdev = lvp->v_rdev;
+ } else {
+ *xdev = svp->v_rdev;
+
+ if (svp->v_type != VBLK)
error = ENOTBLK;
- else if (getmajor(*xdev) >= devcnt)
- error = ENXIO;
- if ((error != 0) ||
- (error = VOP_ACCESS(bvp, aflag, 0, cr, NULL)) != 0 ||
- (error = secpolicy_spec_open(cr, bvp, oflag)) != 0) {
- VN_RELE(bvp);
- return (error);
+ if ((error = secpolicy_spec_open(cr, svp, oflag)) != 0)
+ goto out;
}
- VN_RELE(bvp);
- return (0);
+ if (getmajor(*xdev) >= devcnt) {
+ error = ENXIO;
+ goto out;
+ }
+
+ if ((error = VOP_ACCESS(svp, aflag, 0, cr, NULL)) != 0)
+ goto out;
+
+out:
+ if (svp != NULL)
+ VN_RELE(svp);
+ if (lvp != NULL)
+ VN_RELE(lvp);
+ return (error);
}
static int
pcfs_device_ismounted(
struct vfs *vfsp,