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 "@(#)udf_vfsops.c 1.48 07/10/25 SMI"
+#pragma ident "@(#)udf_vfsops.c 1.49 08/05/07 SMI"
#include <sys/types.h>
#include <sys/t_lock.h>
#include <sys/param.h>
#include <sys/time.h>
@@ -181,11 +181,12 @@
static int32_t
udf_mount(struct vfs *vfsp, struct vnode *mvp,
struct mounta *uap, struct cred *cr)
{
dev_t dev;
- struct vnode *bvp;
+ struct vnode *lvp = NULL;
+ struct vnode *svp = NULL;
struct pathname dpn;
int32_t error;
enum whymountroot why;
int oflag, aflag;
@@ -211,22 +212,34 @@
if (error = pn_get(uap->dir, UIO_USERSPACE, &dpn)) {
return (error);
}
/*
- * Resolve path name of special file being mounted.
+ * Resolve path name of the file being mounted.
*/
if (error = lookupname(uap->spec, UIO_USERSPACE, FOLLOW, NULLVPP,
- &bvp)) {
+ &svp)) {
pn_free(&dpn);
return (error);
}
- 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) {
+ dev = lvp->v_rdev;
+ } else {
+ dev = svp->v_rdev;
+
+ if (svp->v_type != VBLK) {
error = ENOTBLK;
goto out;
}
- dev = bvp->v_rdev;
+ }
/*
* Ensure that this device isn't already mounted,
* unless this is a REMOUNT request
*/
@@ -280,23 +293,28 @@
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) {
+
+ if (lvp == NULL &&
+ (error = secpolicy_spec_open(cr, svp, oflag)) != 0)
goto out;
- }
+ if ((error = VOP_ACCESS(svp, aflag, 0, cr, NULL)) != 0)
+ goto out;
+
/*
* Mount the filesystem.
*/
error = ud_mountfs(vfsp, why, dev, dpn.pn_path, cr, 0);
out:
- VN_RELE(bvp);
+ if (svp != NULL)
+ VN_RELE(svp);
+ if (lvp != NULL)
+ VN_RELE(lvp);
pn_free(&dpn);
-
return (error);
}
@@ -440,13 +458,11 @@
/*
* The total number of inodes is
* the sum of files + directories + free inodes
*/
- sp->f_files = sp->f_ffree +
- udf_vfsp->udf_nfiles +
- udf_vfsp->udf_ndirs;
+ sp->f_files = sp->f_ffree + udf_vfsp->udf_nfiles + udf_vfsp->udf_ndirs;
(void) cmpldev(&d32, vfsp->vfs_dev);
sp->f_fsid = d32;
(void) strcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name);
sp->f_flag = vf_to_stf(vfsp->vfs_flag);
sp->f_namemax = MAXNAMLEN;
@@ -980,12 +996,12 @@
* Verify it and get the location of
* Main Volume Descriptor Sequence
*/
secbp = ud_bread(dev, avd_loc << shift, ANCHOR_VOL_DESC_LEN);
if ((error = geterror(secbp)) != 0) {
- cmn_err(CE_NOTE,
- "udfs : Could not read Anchor Volume Desc %x", error);
+ cmn_err(CE_NOTE, "udfs : Could not read Anchor Volume Desc %x",
+ error);
brelse(secbp);
return (NULL);
}
avdp = (struct anch_vol_desc_ptr *)secbp->b_un.b_addr;
if (ud_verify_tag_and_desc(&avdp->avd_tag, UD_ANCH_VOL_DESC,
@@ -1009,12 +1025,12 @@
vds_loc = udf_vfsp->udf_mvds_loc;
secbp = ud_bread(dev, vds_loc << shift,
udf_vfsp->udf_mvds_len);
if ((error = geterror(secbp)) != 0) {
brelse(secbp);
- cmn_err(CE_NOTE,
- "udfs : Could not read Main Volume Desc %x", error);
+ cmn_err(CE_NOTE, "udfs : Could not read Main Volume Desc %x",
+ error);
vds_loc = udf_vfsp->udf_rvds_loc;
secbp = ud_bread(dev, vds_loc << shift,
udf_vfsp->udf_rvds_len);
if ((error = geterror(secbp)) != 0) {
@@ -1109,12 +1125,16 @@
struct ud_part *pnew, *pold, *part;
pdesc = (struct part_desc *)ttag;
pold = udf_vfsp->udf_parts;
for (i = 0; i < udf_vfsp->udf_npart; i++) {
- if (pold->udp_number ==
+ if (pold->udp_number !=
SWAP_16(pdesc->pd_pnum)) {
+ pold++;
+ continue;
+ }
+
if (SWAP_32(pdesc->pd_vdsn) >
pold->udp_seqno) {
pold->udp_seqno =
SWAP_32(pdesc->pd_vdsn);
pold->udp_access =
@@ -1124,12 +1144,10 @@
pold->udp_length =
SWAP_32(pdesc->pd_part_length);
}
goto loop_end;
}
- pold ++;
- }
pold = udf_vfsp->udf_parts;
udf_vfsp->udf_npart++;
pnew = kmem_zalloc(udf_vfsp->udf_npart *
sizeof (struct ud_part), KM_SLEEP);
udf_vfsp->udf_parts = pnew;
@@ -1262,17 +1280,17 @@
typ1 = (struct pmap_typ1 *)hdr;
map = udf_vfsp->udf_maps;
udf_vfsp->udf_maps =
kmem_zalloc(sizeof (struct ud_map) *
- (udf_vfsp->udf_nmaps + 1),
- KM_SLEEP);
+ (udf_vfsp->udf_nmaps + 1), KM_SLEEP);
if (map != NULL) {
bcopy(map, udf_vfsp->udf_maps,
- sizeof (struct ud_map) * udf_vfsp->udf_nmaps);
- kmem_free(map,
- sizeof (struct ud_map) * udf_vfsp->udf_nmaps);
+ sizeof (struct ud_map) *
+ udf_vfsp->udf_nmaps);
+ kmem_free(map, sizeof (struct ud_map) *
+ udf_vfsp->udf_nmaps);
}
map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps;
map->udm_flags = UDM_MAP_NORM;
map->udm_vsn = SWAP_16(typ1->map1_vsn);
map->udm_pn = SWAP_16(typ1->map1_pn);
@@ -1289,12 +1307,11 @@
* we donot
*/
map = udf_vfsp->udf_maps;
udf_vfsp->udf_maps =
kmem_zalloc(sizeof (struct ud_map) *
- (udf_vfsp->udf_nmaps + 1),
- KM_SLEEP);
+ (udf_vfsp->udf_nmaps + 1), KM_SLEEP);
if (map != NULL) {
bcopy(map, udf_vfsp->udf_maps,
sizeof (struct ud_map) *
udf_vfsp->udf_nmaps);
kmem_free(map,