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


   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "@(#)hsfs_vfsops.c      1.97    07/10/25 SMI"
  27 
  28 /*
  29  * VFS operations for High Sierra filesystem
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/isa_defs.h>
  34 #include <sys/t_lock.h>
  35 #include <sys/param.h>
  36 #include <sys/systm.h>
  37 #include <sys/sysmacros.h>
  38 #include <sys/kmem.h>
  39 #include <sys/signal.h>
  40 #include <sys/user.h>
  41 #include <sys/proc.h>
  42 #include <sys/disp.h>
  43 #include <sys/buf.h>
  44 #include <sys/pathname.h>
  45 #include <sys/vfs.h>
  46 #include <sys/vfs_opreg.h>


1326         if (hvp->lbn_size & ~(1 << hvp->lbn_shift)) {
1327                 cmn_err(CE_NOTE,
1328                     "hsfs: %d-byte logical block size not supported",
1329                     hvp->lbn_size);
1330                 return (EINVAL);
1331         }
1332         return (hs_parsedir(fsp, ISO_ROOT_DIR(volp), &hvp->root_dir,
1333             (char *)NULL, (int *)NULL, IDE_ROOT_DIR_REC_SIZE));
1334 }
1335 
1336 /*
1337  * Common code for mount and umount.
1338  * Check that the user's argument is a reasonable
1339  * thing on which to mount, and return the device number if so.
1340  */
1341 static int
1342 hs_getmdev(struct vfs *vfsp, char *fspec, int flags, dev_t *pdev, mode_t *mode,
1343     cred_t *cr)
1344 {
1345         int error;
1346         struct vnode *vp;


1347         struct vattr vap;
1348         dev_t dev;


1349 
1350         /*
1351          * Get the device to be mounted
1352          */
1353         error = lookupname(fspec, (flags & MS_SYSSPACE) ?
1354             UIO_SYSSPACE : UIO_USERSPACE, FOLLOW, NULLVPP, &vp);
1355         if (error) {
1356                 if (error == ENOENT) {
1357                         return (ENODEV);        /* needs translation */

1358                 }
1359                 return (error);














1360         }
1361         if (vp->v_type != VBLK) {
1362                 VN_RELE(vp);
1363                 return (ENOTBLK);
1364         }

1365         /*
1366          * Can we read from the device?
1367          */
1368         if ((error = VOP_ACCESS(vp, VREAD, 0, cr, NULL)) != 0 ||
1369             (error = secpolicy_spec_open(cr, vp, FREAD)) != 0) {
1370                 VN_RELE(vp);
1371                 return (error);
1372         }
1373 
1374         vap.va_mask = AT_MODE;          /* get protection mode */
1375         (void) VOP_GETATTR(vp, &vap, 0, CRED(), NULL);
1376         *mode = vap.va_mode;
1377 
1378         dev = *pdev = vp->v_rdev;
1379         VN_RELE(vp);
1380 


1381         /*
1382          * Ensure that this device isn't already mounted,
1383          * unless this is a REMOUNT request or we are told to suppress
1384          * mount checks.
1385          */
1386         if ((flags & MS_NOCHECK) == 0) {
1387                 if (vfs_devmounting(dev, vfsp))
1388                         return (EBUSY);
1389                 if (vfs_devismounted(dev) && !(flags & MS_REMOUNT))
1390                         return (EBUSY);
1391         }
1392 
1393         if (getmajor(*pdev) >= devcnt)
1394                 return (ENXIO);
1395         return (0);









1396 }
1397 
1398 static void
1399 hs_copylabel(struct hs_volume *hvp, unsigned char *label, int isjoliet)
1400 {
1401         char    lbuf[64];       /* hs_joliet_cp() creates 48 bytes at most */
1402 
1403         if (isjoliet) {
1404                 /*
1405                  * hs_joliet_cp() will output 16..48 bytes.
1406                  * We need to clear 'lbuf' to avoid junk chars past byte 15.
1407                  */
1408                 bzero(lbuf, sizeof (lbuf));
1409                 (void) hs_joliet_cp((char *)label, lbuf, 32);
1410                 label = (unsigned char *)lbuf;
1411         }
1412         /* cdrom volid is at most 32 bytes */
1413         bcopy(label, hvp->vol_id, 32);
1414         hvp->vol_id[31] = NULL;
1415 }




   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "@(#)hsfs_vfsops.c      1.98    08/05/07 SMI"
  27 
  28 /*
  29  * VFS operations for High Sierra filesystem
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/isa_defs.h>
  34 #include <sys/t_lock.h>
  35 #include <sys/param.h>
  36 #include <sys/systm.h>
  37 #include <sys/sysmacros.h>
  38 #include <sys/kmem.h>
  39 #include <sys/signal.h>
  40 #include <sys/user.h>
  41 #include <sys/proc.h>
  42 #include <sys/disp.h>
  43 #include <sys/buf.h>
  44 #include <sys/pathname.h>
  45 #include <sys/vfs.h>
  46 #include <sys/vfs_opreg.h>


1326         if (hvp->lbn_size & ~(1 << hvp->lbn_shift)) {
1327                 cmn_err(CE_NOTE,
1328                     "hsfs: %d-byte logical block size not supported",
1329                     hvp->lbn_size);
1330                 return (EINVAL);
1331         }
1332         return (hs_parsedir(fsp, ISO_ROOT_DIR(volp), &hvp->root_dir,
1333             (char *)NULL, (int *)NULL, IDE_ROOT_DIR_REC_SIZE));
1334 }
1335 
1336 /*
1337  * Common code for mount and umount.
1338  * Check that the user's argument is a reasonable
1339  * thing on which to mount, and return the device number if so.
1340  */
1341 static int
1342 hs_getmdev(struct vfs *vfsp, char *fspec, int flags, dev_t *pdev, mode_t *mode,
1343     cred_t *cr)
1344 {
1345         int error;
1346         struct vnode *svp = NULL;
1347         struct vnode *lvp = NULL;
1348         struct vnode *bvp;
1349         struct vattr vap;
1350         dev_t dev;
1351         enum uio_seg fromspace = (flags & MS_SYSSPACE) ?
1352             UIO_SYSSPACE : UIO_USERSPACE;
1353 
1354         /*
1355          * Look up the device/file to be mounted.
1356          */
1357         error = lookupname(fspec, fromspace, FOLLOW, NULLVPP, &svp);

1358         if (error) {
1359                 if (error == ENOENT)
1360                         error = ENODEV;
1361                 goto out;
1362         }
1363 
1364         error = vfs_get_lofi(vfsp, &lvp);
1365 
1366         if (error > 0) {
1367                 if (error == ENOENT)
1368                         error = ENODEV;
1369                 goto out;
1370         } else if (error == 0) {
1371                 bvp = lvp;
1372         } else {
1373                 bvp = svp;
1374 
1375                 if (bvp->v_type != VBLK) {
1376                         error = ENOTBLK;
1377                         goto out;
1378                 }
1379 
1380                 if ((error = secpolicy_spec_open(cr, bvp, FREAD)) != 0)
1381                         goto out;
1382         }
1383 
1384         /*
1385          * Can we read from the device/file ?
1386          */
1387         if ((error = VOP_ACCESS(svp, VREAD, 0, cr, NULL)) != 0)
1388                 goto out;



1389 
1390         vap.va_mask = AT_MODE;          /* get protection mode */
1391         (void) VOP_GETATTR(bvp, &vap, 0, CRED(), NULL);
1392         *mode = vap.va_mode;
1393 
1394         dev = *pdev = bvp->v_rdev;

1395 
1396         error = EBUSY;
1397 
1398         /*
1399          * Ensure that this device isn't already mounted,
1400          * unless this is a REMOUNT request or we are told to suppress
1401          * mount checks.
1402          */
1403         if ((flags & MS_NOCHECK) == 0) {
1404                 if (vfs_devmounting(dev, vfsp))
1405                         goto out;
1406                 if (vfs_devismounted(dev) && !(flags & MS_REMOUNT))
1407                         goto out;
1408         }
1409 
1410         if (getmajor(*pdev) >= devcnt) {
1411                 error = ENXIO;
1412                 goto out;
1413         }
1414 
1415         error = 0;
1416 out:
1417         if (svp != NULL)
1418                 VN_RELE(svp);
1419         if (lvp != NULL)
1420                 VN_RELE(lvp);
1421         return (error);
1422 }
1423 
1424 static void
1425 hs_copylabel(struct hs_volume *hvp, unsigned char *label, int isjoliet)
1426 {
1427         char    lbuf[64];       /* hs_joliet_cp() creates 48 bytes at most */
1428 
1429         if (isjoliet) {
1430                 /*
1431                  * hs_joliet_cp() will output 16..48 bytes.
1432                  * We need to clear 'lbuf' to avoid junk chars past byte 15.
1433                  */
1434                 bzero(lbuf, sizeof (lbuf));
1435                 (void) hs_joliet_cp((char *)label, lbuf, 32);
1436                 label = (unsigned char *)lbuf;
1437         }
1438         /* cdrom volid is at most 32 bytes */
1439         bcopy(label, hvp->vol_id, 32);
1440         hvp->vol_id[31] = NULL;
1441 }