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,