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   "@(#)udf_vfsops.c       1.48    07/10/25 SMI"
  27 
  28 #include <sys/types.h>
  29 #include <sys/t_lock.h>
  30 #include <sys/param.h>
  31 #include <sys/time.h>
  32 #include <sys/systm.h>
  33 #include <sys/sysmacros.h>
  34 #include <sys/resource.h>
  35 #include <sys/signal.h>
  36 #include <sys/cred.h>
  37 #include <sys/user.h>
  38 #include <sys/buf.h>
  39 #include <sys/vfs.h>
  40 #include <sys/vfs_opreg.h>
  41 #include <sys/stat.h>
  42 #include <sys/vnode.h>
  43 #include <sys/mode.h>
  44 #include <sys/proc.h>
  45 #include <sys/disp.h>
  46 #include <sys/file.h>


 166         return (mod_info(&modlinkage, modinfop));
 167 }
 168 
 169 
 170 /* -------------------- vfs routines -------------------- */
 171 
 172 /*
 173  * XXX - this appears only to be used by the VM code to handle the case where
 174  * UNIX is running off the mini-root.  That probably wants to be done
 175  * differently.
 176  */
 177 struct vnode *rootvp;
 178 #ifndef __lint
 179 _NOTE(SCHEME_PROTECTS_DATA("safe sharing", rootvp))
 180 #endif
 181 static int32_t
 182 udf_mount(struct vfs *vfsp, struct vnode *mvp,
 183         struct mounta *uap, struct cred *cr)
 184 {
 185         dev_t dev;
 186         struct vnode *bvp;

 187         struct pathname dpn;
 188         int32_t error;
 189         enum whymountroot why;
 190         int oflag, aflag;
 191 
 192         ud_printf("udf_mount\n");
 193 
 194         if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0) {
 195                 return (error);
 196         }
 197 
 198         if (mvp->v_type != VDIR) {
 199                 return (ENOTDIR);
 200         }
 201 
 202         mutex_enter(&mvp->v_lock);
 203         if ((uap->flags & MS_REMOUNT) == 0 &&
 204             (uap->flags & MS_OVERLAY) == 0 &&
 205                 (mvp->v_count != 1 || (mvp->v_flag & VROOT))) {
 206                         mutex_exit(&mvp->v_lock);
 207                         return (EBUSY);
 208         }
 209         mutex_exit(&mvp->v_lock);
 210 
 211         if (error = pn_get(uap->dir, UIO_USERSPACE, &dpn)) {
 212                 return (error);
 213         }
 214 
 215         /*
 216          * Resolve path name of special file being mounted.
 217          */
 218         if (error = lookupname(uap->spec, UIO_USERSPACE, FOLLOW, NULLVPP,
 219             &bvp)) {
 220                 pn_free(&dpn);
 221                 return (error);
 222         }
 223         if (bvp->v_type != VBLK) {












 224                 error = ENOTBLK;
 225                 goto out;
 226         }
 227         dev = bvp->v_rdev;
 228 
 229         /*
 230          * Ensure that this device isn't already mounted,
 231          * unless this is a REMOUNT request
 232          */
 233         if (vfs_devmounting(dev, vfsp)) {
 234                 error = EBUSY;
 235                 goto out;
 236         }
 237         if (vfs_devismounted(dev)) {
 238                 if (uap->flags & MS_REMOUNT) {
 239                         why = ROOT_REMOUNT;
 240                 } else {
 241                         error = EBUSY;
 242                         goto out;
 243                 }
 244         } else {
 245                 why = ROOT_INIT;
 246         }
 247         if (getmajor(dev) >= devcnt) {


 265          */
 266         if (uap->flags & MS_RDONLY) {
 267                 vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0);
 268         }
 269         if (uap->flags & MS_NOSUID) {
 270                 vfs_setmntopt(vfsp, MNTOPT_NOSUID, NULL, 0);
 271         }
 272 
 273         /*
 274          * Verify that the caller can open the device special file as
 275          * required.  It is not until this moment that we know whether
 276          * we're mounting "ro" or not.
 277          */
 278         if ((vfsp->vfs_flag & VFS_RDONLY) != 0) {
 279                 oflag = FREAD;
 280                 aflag = VREAD;
 281         } else {
 282                 oflag = FREAD | FWRITE;
 283                 aflag = VREAD | VWRITE;
 284         }
 285         if ((error = VOP_ACCESS(bvp, aflag, 0, cr, NULL)) != 0 ||
 286             (error = secpolicy_spec_open(cr, bvp, oflag)) != 0) {

 287                 goto out;
 288         }
 289 



 290         /*
 291          * Mount the filesystem.
 292          */
 293         error = ud_mountfs(vfsp, why, dev, dpn.pn_path, cr, 0);
 294 out:
 295         VN_RELE(bvp);



 296         pn_free(&dpn);
 297 
 298         return (error);
 299 }
 300 
 301 
 302 
 303 /*
 304  * unmount the file system pointed
 305  * by vfsp
 306  */
 307 /* ARGSUSED */
 308 static int32_t
 309 udf_unmount(struct vfs *vfsp, int fflag, struct cred *cr)
 310 {
 311         struct udf_vfs *udf_vfsp;
 312         struct vnode *bvp, *rvp;
 313         struct ud_inode *rip;
 314         int32_t flag;
 315 
 316         ud_printf("udf_unmount\n");
 317 


 425         for (index = 0; index < udf_vfsp->udf_npart; index++) {
 426                 sp->f_blocks += parts->udp_nblocks;
 427                 sp->f_bfree += parts->udp_nfree;
 428                 parts++;
 429         }
 430         sp->f_bavail = sp->f_bfree;
 431 
 432         /*
 433          * Since there are no real inodes allocated
 434          * we will approximate
 435          * each new file will occupy :
 436          * 38(over head each dent) + MAXNAMLEN / 2 + inode_size(==block size)
 437          */
 438         sp->f_ffree = sp->f_favail =
 439                 (sp->f_bavail * sp->f_bsize) / (146 + sp->f_bsize);
 440 
 441         /*
 442          * The total number of inodes is
 443          * the sum of files + directories + free inodes
 444          */
 445         sp->f_files = sp->f_ffree +
 446                         udf_vfsp->udf_nfiles +
 447                         udf_vfsp->udf_ndirs;
 448         (void) cmpldev(&d32, vfsp->vfs_dev);
 449         sp->f_fsid = d32;
 450         (void) strcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name);
 451         sp->f_flag = vf_to_stf(vfsp->vfs_flag);
 452         sp->f_namemax = MAXNAMLEN;
 453         (void) strcpy(sp->f_fstr, udf_vfsp->udf_volid);
 454 
 455         mutex_exit(&udf_vfsp->udf_lock);
 456 
 457         return (0);
 458 }
 459 
 460 
 461 /*
 462  * Flush any pending I/O to file system vfsp.
 463  * The ud_update() routine will only flush *all* udf files.
 464  */
 465 /*ARGSUSED*/
 466 /* ARGSUSED */
 467 static int32_t


 965         struct ud_map *map;
 966         int32_t desc_len;
 967 
 968         ud_printf("ud_validate_and_fill_superblock\n");
 969 
 970         if (bsize < DEV_BSIZE) {
 971                 return (NULL);
 972         }
 973         shift = 0;
 974         while ((bsize >> shift) > DEV_BSIZE) {
 975                 shift++;
 976         }
 977 
 978         /*
 979          * Read Anchor Volume Descriptor
 980          * Verify it and get the location of
 981          * Main Volume Descriptor Sequence
 982          */
 983         secbp = ud_bread(dev, avd_loc << shift, ANCHOR_VOL_DESC_LEN);
 984         if ((error = geterror(secbp)) != 0) {
 985                 cmn_err(CE_NOTE,
 986                 "udfs : Could not read Anchor Volume Desc %x", error);
 987                 brelse(secbp);
 988                 return (NULL);
 989         }
 990         avdp = (struct anch_vol_desc_ptr *)secbp->b_un.b_addr;
 991         if (ud_verify_tag_and_desc(&avdp->avd_tag, UD_ANCH_VOL_DESC,
 992             avd_loc, 1, ANCHOR_VOL_DESC_LEN) != 0) {
 993                 brelse(secbp);
 994                 return (NULL);
 995         }
 996         udf_vfsp = (struct udf_vfs *)
 997                 kmem_zalloc(sizeof (struct udf_vfs), KM_SLEEP);
 998         udf_vfsp->udf_mvds_loc = SWAP_32(avdp->avd_main_vdse.ext_loc);
 999         udf_vfsp->udf_mvds_len = SWAP_32(avdp->avd_main_vdse.ext_len);
1000         udf_vfsp->udf_rvds_loc = SWAP_32(avdp->avd_res_vdse.ext_loc);
1001         udf_vfsp->udf_rvds_len = SWAP_32(avdp->avd_res_vdse.ext_len);
1002         secbp->b_flags = B_AGE | B_STALE;
1003         brelse(secbp);
1004 
1005         /*
1006          * Read Main Volume Descriptor Sequence
1007          * and process it
1008          */
1009         vds_loc = udf_vfsp->udf_mvds_loc;
1010         secbp = ud_bread(dev, vds_loc << shift,
1011                         udf_vfsp->udf_mvds_len);
1012         if ((error = geterror(secbp)) != 0) {
1013                 brelse(secbp);
1014                 cmn_err(CE_NOTE,
1015                 "udfs : Could not read Main Volume Desc %x", error);
1016 
1017                 vds_loc = udf_vfsp->udf_rvds_loc;
1018                 secbp = ud_bread(dev, vds_loc << shift,
1019                         udf_vfsp->udf_rvds_len);
1020                 if ((error = geterror(secbp)) != 0) {
1021                         brelse(secbp);
1022                         cmn_err(CE_NOTE,
1023                         "udfs : Could not read Res Volume Desc %x", error);
1024                         return (NULL);
1025                 }
1026         }
1027 
1028         udf_vfsp->udf_vds = ngeteblk(udf_vfsp->udf_mvds_len);
1029         bp = udf_vfsp->udf_vds;
1030         bp->b_edev = dev;
1031         bp->b_dev = cmpdev(dev);
1032         bp->b_blkno = vds_loc << shift;
1033         bp->b_bcount = udf_vfsp->udf_mvds_len;
1034         bcopy(secbp->b_un.b_addr, bp->b_un.b_addr, udf_vfsp->udf_mvds_len);
1035         secbp->b_flags |= B_STALE | B_AGE;


1094                                                 lvd->lvd_lvid, 128) == 0)) {
1095                                         if (SWAP_32(olvd->lvd_vdsn) <
1096                                                 SWAP_32(lvd->lvd_vdsn)) {
1097                                                 udf_vfsp->udf_lvd = lvd;
1098                                         }
1099                                 } else {
1100                                         goto out;
1101                                 }
1102                         }
1103                 } else if (ud_verify_tag_and_desc(ttag, UD_PART_DESC,
1104                     vds_loc + (index >> shift),
1105                     1, desc_len) == 0) {
1106                         int32_t i;
1107                         struct phdr_desc *hdr;
1108                         struct part_desc *pdesc;
1109                         struct ud_part *pnew, *pold, *part;
1110 
1111                         pdesc = (struct part_desc *)ttag;
1112                         pold = udf_vfsp->udf_parts;
1113                         for (i = 0; i < udf_vfsp->udf_npart; i++) {
1114                                 if (pold->udp_number ==
1115                                         SWAP_16(pdesc->pd_pnum)) {




1116                                         if (SWAP_32(pdesc->pd_vdsn) >
1117                                                 pold->udp_seqno) {
1118                                                 pold->udp_seqno =
1119                                                         SWAP_32(pdesc->pd_vdsn);
1120                                                 pold->udp_access =
1121                                                 SWAP_32(pdesc->pd_acc_type);
1122                                                 pold->udp_start =
1123                                                 SWAP_32(pdesc->pd_part_start);
1124                                                 pold->udp_length =
1125                                                 SWAP_32(pdesc->pd_part_length);
1126                                         }
1127                                         goto loop_end;
1128                                 }
1129                                 pold ++;
1130                         }
1131                         pold = udf_vfsp->udf_parts;
1132                         udf_vfsp->udf_npart++;
1133                         pnew = kmem_zalloc(udf_vfsp->udf_npart *
1134                                         sizeof (struct ud_part), KM_SLEEP);
1135                         udf_vfsp->udf_parts = pnew;
1136                         if (pold) {
1137                                 bcopy(pold, pnew,
1138                                         sizeof (struct ud_part) *
1139                                         (udf_vfsp->udf_npart - 1));
1140                                 kmem_free(pold,
1141                                         sizeof (struct ud_part) *
1142                                         (udf_vfsp->udf_npart - 1));
1143                         }
1144                         part = pnew + (udf_vfsp->udf_npart - 1);
1145                         part->udp_number = SWAP_16(pdesc->pd_pnum);
1146                         part->udp_seqno = SWAP_32(pdesc->pd_vdsn);
1147                         part->udp_access = SWAP_32(pdesc->pd_acc_type);
1148                         part->udp_start = SWAP_32(pdesc->pd_part_start);
1149                         part->udp_length = SWAP_32(pdesc->pd_part_length);
1150                         part->udp_last_alloc = 0;


1247                                 udf_vfsp->udf_parts[index].udp_access;
1248                 }
1249         }
1250         if ((udf_vfsp->udf_mtype < UDF_MT_RO) ||
1251                 (udf_vfsp->udf_mtype > UDF_MT_OW)) {
1252                 udf_vfsp->udf_mtype = UDF_MT_RO;
1253         }
1254 
1255         udf_vfsp->udf_nmaps = 0;
1256         hdr = (struct pmap_hdr *)udf_vfsp->udf_lvd->lvd_pmaps;
1257         count = SWAP_32(udf_vfsp->udf_lvd->lvd_num_pmaps);
1258         for (index = 0; index < count; index++) {
1259 
1260                 if ((hdr->maph_type == MAP_TYPE1) &&
1261                         (hdr->maph_length == MAP_TYPE1_LEN)) {
1262                         typ1 = (struct pmap_typ1 *)hdr;
1263 
1264                         map = udf_vfsp->udf_maps;
1265                         udf_vfsp->udf_maps =
1266                                 kmem_zalloc(sizeof (struct ud_map) *
1267                                         (udf_vfsp->udf_nmaps + 1),
1268                                         KM_SLEEP);
1269                         if (map != NULL) {
1270                                 bcopy(map, udf_vfsp->udf_maps,
1271                                 sizeof (struct ud_map) * udf_vfsp->udf_nmaps);
1272                                 kmem_free(map,
1273                                 sizeof (struct ud_map) * udf_vfsp->udf_nmaps);

1274                         }
1275                         map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps;
1276                         map->udm_flags = UDM_MAP_NORM;
1277                         map->udm_vsn = SWAP_16(typ1->map1_vsn);
1278                         map->udm_pn = SWAP_16(typ1->map1_pn);
1279                         udf_vfsp->udf_nmaps ++;
1280                 } else if ((hdr->maph_type == MAP_TYPE2) &&
1281                         (hdr->maph_length == MAP_TYPE2_LEN)) {
1282                         typ2 = (struct pmap_typ2 *)hdr;
1283 
1284                         if (strncmp(typ2->map2_pti.reg_id,
1285                                 UDF_VIRT_PART, 23) == 0) {
1286                                 /*
1287                                  * Add this to the normal
1288                                  * partition table so that
1289                                  * we donot
1290                                  */
1291                                 map = udf_vfsp->udf_maps;
1292                                 udf_vfsp->udf_maps =
1293                                         kmem_zalloc(sizeof (struct ud_map) *
1294                                                 (udf_vfsp->udf_nmaps + 1),
1295                                                 KM_SLEEP);
1296                                 if (map != NULL) {
1297                                         bcopy(map, udf_vfsp->udf_maps,
1298                                                 sizeof (struct ud_map) *
1299                                                 udf_vfsp->udf_nmaps);
1300                                         kmem_free(map,
1301                                                 sizeof (struct ud_map) *
1302                                                 udf_vfsp->udf_nmaps);
1303                                 }
1304                                 map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps;
1305                                 map->udm_flags = UDM_MAP_VPM;
1306                                 map->udm_vsn = SWAP_16(typ2->map2_vsn);
1307                                 map->udm_pn = SWAP_16(typ2->map2_pn);
1308                                 udf_vfsp->udf_nmaps ++;
1309                                 if (error = ud_get_last_block(dev, &lblkno)) {
1310                                         goto out;
1311                                 }
1312                                 if (error = ud_val_get_vat(udf_vfsp, dev,
1313                                         lblkno, map)) {
1314                                         goto out;
1315                                 }




   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   "@(#)udf_vfsops.c       1.49    08/05/07 SMI"
  27 
  28 #include <sys/types.h>
  29 #include <sys/t_lock.h>
  30 #include <sys/param.h>
  31 #include <sys/time.h>
  32 #include <sys/systm.h>
  33 #include <sys/sysmacros.h>
  34 #include <sys/resource.h>
  35 #include <sys/signal.h>
  36 #include <sys/cred.h>
  37 #include <sys/user.h>
  38 #include <sys/buf.h>
  39 #include <sys/vfs.h>
  40 #include <sys/vfs_opreg.h>
  41 #include <sys/stat.h>
  42 #include <sys/vnode.h>
  43 #include <sys/mode.h>
  44 #include <sys/proc.h>
  45 #include <sys/disp.h>
  46 #include <sys/file.h>


 166         return (mod_info(&modlinkage, modinfop));
 167 }
 168 
 169 
 170 /* -------------------- vfs routines -------------------- */
 171 
 172 /*
 173  * XXX - this appears only to be used by the VM code to handle the case where
 174  * UNIX is running off the mini-root.  That probably wants to be done
 175  * differently.
 176  */
 177 struct vnode *rootvp;
 178 #ifndef __lint
 179 _NOTE(SCHEME_PROTECTS_DATA("safe sharing", rootvp))
 180 #endif
 181 static int32_t
 182 udf_mount(struct vfs *vfsp, struct vnode *mvp,
 183         struct mounta *uap, struct cred *cr)
 184 {
 185         dev_t dev;
 186         struct vnode *lvp = NULL;
 187         struct vnode *svp = NULL;
 188         struct pathname dpn;
 189         int32_t error;
 190         enum whymountroot why;
 191         int oflag, aflag;
 192 
 193         ud_printf("udf_mount\n");
 194 
 195         if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0) {
 196                 return (error);
 197         }
 198 
 199         if (mvp->v_type != VDIR) {
 200                 return (ENOTDIR);
 201         }
 202 
 203         mutex_enter(&mvp->v_lock);
 204         if ((uap->flags & MS_REMOUNT) == 0 &&
 205             (uap->flags & MS_OVERLAY) == 0 &&
 206             (mvp->v_count != 1 || (mvp->v_flag & VROOT))) {
 207                         mutex_exit(&mvp->v_lock);
 208                         return (EBUSY);
 209         }
 210         mutex_exit(&mvp->v_lock);
 211 
 212         if (error = pn_get(uap->dir, UIO_USERSPACE, &dpn)) {
 213                 return (error);
 214         }
 215 
 216         /*
 217          * Resolve path name of the file being mounted.
 218          */
 219         if (error = lookupname(uap->spec, UIO_USERSPACE, FOLLOW, NULLVPP,
 220             &svp)) {
 221                 pn_free(&dpn);
 222                 return (error);
 223         }
 224 
 225         error = vfs_get_lofi(vfsp, &lvp);
 226 
 227         if (error > 0) {
 228                 if (error == ENOENT)
 229                         error = ENODEV;
 230                 goto out;
 231         } else if (error == 0) {
 232                 dev = lvp->v_rdev;
 233         } else {
 234                 dev = svp->v_rdev;
 235 
 236                 if (svp->v_type != VBLK) {
 237                         error = ENOTBLK;
 238                         goto out;
 239                 }
 240         }
 241 
 242         /*
 243          * Ensure that this device isn't already mounted,
 244          * unless this is a REMOUNT request
 245          */
 246         if (vfs_devmounting(dev, vfsp)) {
 247                 error = EBUSY;
 248                 goto out;
 249         }
 250         if (vfs_devismounted(dev)) {
 251                 if (uap->flags & MS_REMOUNT) {
 252                         why = ROOT_REMOUNT;
 253                 } else {
 254                         error = EBUSY;
 255                         goto out;
 256                 }
 257         } else {
 258                 why = ROOT_INIT;
 259         }
 260         if (getmajor(dev) >= devcnt) {


 278          */
 279         if (uap->flags & MS_RDONLY) {
 280                 vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0);
 281         }
 282         if (uap->flags & MS_NOSUID) {
 283                 vfs_setmntopt(vfsp, MNTOPT_NOSUID, NULL, 0);
 284         }
 285 
 286         /*
 287          * Verify that the caller can open the device special file as
 288          * required.  It is not until this moment that we know whether
 289          * we're mounting "ro" or not.
 290          */
 291         if ((vfsp->vfs_flag & VFS_RDONLY) != 0) {
 292                 oflag = FREAD;
 293                 aflag = VREAD;
 294         } else {
 295                 oflag = FREAD | FWRITE;
 296                 aflag = VREAD | VWRITE;
 297         }
 298 
 299         if (lvp == NULL &&
 300             (error = secpolicy_spec_open(cr, svp, oflag)) != 0)
 301                 goto out;

 302 
 303         if ((error = VOP_ACCESS(svp, aflag, 0, cr, NULL)) != 0)
 304                 goto out;
 305 
 306         /*
 307          * Mount the filesystem.
 308          */
 309         error = ud_mountfs(vfsp, why, dev, dpn.pn_path, cr, 0);
 310 out:
 311         if (svp != NULL)
 312                 VN_RELE(svp);
 313         if (lvp != NULL)
 314                 VN_RELE(lvp);
 315         pn_free(&dpn);

 316         return (error);
 317 }
 318 
 319 
 320 
 321 /*
 322  * unmount the file system pointed
 323  * by vfsp
 324  */
 325 /* ARGSUSED */
 326 static int32_t
 327 udf_unmount(struct vfs *vfsp, int fflag, struct cred *cr)
 328 {
 329         struct udf_vfs *udf_vfsp;
 330         struct vnode *bvp, *rvp;
 331         struct ud_inode *rip;
 332         int32_t flag;
 333 
 334         ud_printf("udf_unmount\n");
 335 


 443         for (index = 0; index < udf_vfsp->udf_npart; index++) {
 444                 sp->f_blocks += parts->udp_nblocks;
 445                 sp->f_bfree += parts->udp_nfree;
 446                 parts++;
 447         }
 448         sp->f_bavail = sp->f_bfree;
 449 
 450         /*
 451          * Since there are no real inodes allocated
 452          * we will approximate
 453          * each new file will occupy :
 454          * 38(over head each dent) + MAXNAMLEN / 2 + inode_size(==block size)
 455          */
 456         sp->f_ffree = sp->f_favail =
 457             (sp->f_bavail * sp->f_bsize) / (146 + sp->f_bsize);
 458 
 459         /*
 460          * The total number of inodes is
 461          * the sum of files + directories + free inodes
 462          */
 463         sp->f_files = sp->f_ffree + udf_vfsp->udf_nfiles + udf_vfsp->udf_ndirs;


 464         (void) cmpldev(&d32, vfsp->vfs_dev);
 465         sp->f_fsid = d32;
 466         (void) strcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name);
 467         sp->f_flag = vf_to_stf(vfsp->vfs_flag);
 468         sp->f_namemax = MAXNAMLEN;
 469         (void) strcpy(sp->f_fstr, udf_vfsp->udf_volid);
 470 
 471         mutex_exit(&udf_vfsp->udf_lock);
 472 
 473         return (0);
 474 }
 475 
 476 
 477 /*
 478  * Flush any pending I/O to file system vfsp.
 479  * The ud_update() routine will only flush *all* udf files.
 480  */
 481 /*ARGSUSED*/
 482 /* ARGSUSED */
 483 static int32_t


 981         struct ud_map *map;
 982         int32_t desc_len;
 983 
 984         ud_printf("ud_validate_and_fill_superblock\n");
 985 
 986         if (bsize < DEV_BSIZE) {
 987                 return (NULL);
 988         }
 989         shift = 0;
 990         while ((bsize >> shift) > DEV_BSIZE) {
 991                 shift++;
 992         }
 993 
 994         /*
 995          * Read Anchor Volume Descriptor
 996          * Verify it and get the location of
 997          * Main Volume Descriptor Sequence
 998          */
 999         secbp = ud_bread(dev, avd_loc << shift, ANCHOR_VOL_DESC_LEN);
1000         if ((error = geterror(secbp)) != 0) {
1001                 cmn_err(CE_NOTE, "udfs : Could not read Anchor Volume Desc %x",
1002                     error);
1003                 brelse(secbp);
1004                 return (NULL);
1005         }
1006         avdp = (struct anch_vol_desc_ptr *)secbp->b_un.b_addr;
1007         if (ud_verify_tag_and_desc(&avdp->avd_tag, UD_ANCH_VOL_DESC,
1008             avd_loc, 1, ANCHOR_VOL_DESC_LEN) != 0) {
1009                 brelse(secbp);
1010                 return (NULL);
1011         }
1012         udf_vfsp = (struct udf_vfs *)
1013             kmem_zalloc(sizeof (struct udf_vfs), KM_SLEEP);
1014         udf_vfsp->udf_mvds_loc = SWAP_32(avdp->avd_main_vdse.ext_loc);
1015         udf_vfsp->udf_mvds_len = SWAP_32(avdp->avd_main_vdse.ext_len);
1016         udf_vfsp->udf_rvds_loc = SWAP_32(avdp->avd_res_vdse.ext_loc);
1017         udf_vfsp->udf_rvds_len = SWAP_32(avdp->avd_res_vdse.ext_len);
1018         secbp->b_flags = B_AGE | B_STALE;
1019         brelse(secbp);
1020 
1021         /*
1022          * Read Main Volume Descriptor Sequence
1023          * and process it
1024          */
1025         vds_loc = udf_vfsp->udf_mvds_loc;
1026         secbp = ud_bread(dev, vds_loc << shift,
1027             udf_vfsp->udf_mvds_len);
1028         if ((error = geterror(secbp)) != 0) {
1029                 brelse(secbp);
1030                 cmn_err(CE_NOTE, "udfs : Could not read Main Volume Desc %x",
1031                     error);
1032 
1033                 vds_loc = udf_vfsp->udf_rvds_loc;
1034                 secbp = ud_bread(dev, vds_loc << shift,
1035                     udf_vfsp->udf_rvds_len);
1036                 if ((error = geterror(secbp)) != 0) {
1037                         brelse(secbp);
1038                         cmn_err(CE_NOTE,
1039                         "udfs : Could not read Res Volume Desc %x", error);
1040                         return (NULL);
1041                 }
1042         }
1043 
1044         udf_vfsp->udf_vds = ngeteblk(udf_vfsp->udf_mvds_len);
1045         bp = udf_vfsp->udf_vds;
1046         bp->b_edev = dev;
1047         bp->b_dev = cmpdev(dev);
1048         bp->b_blkno = vds_loc << shift;
1049         bp->b_bcount = udf_vfsp->udf_mvds_len;
1050         bcopy(secbp->b_un.b_addr, bp->b_un.b_addr, udf_vfsp->udf_mvds_len);
1051         secbp->b_flags |= B_STALE | B_AGE;


1110                                     lvd->lvd_lvid, 128) == 0)) {
1111                                         if (SWAP_32(olvd->lvd_vdsn) <
1112                                             SWAP_32(lvd->lvd_vdsn)) {
1113                                                 udf_vfsp->udf_lvd = lvd;
1114                                         }
1115                                 } else {
1116                                         goto out;
1117                                 }
1118                         }
1119                 } else if (ud_verify_tag_and_desc(ttag, UD_PART_DESC,
1120                     vds_loc + (index >> shift),
1121                     1, desc_len) == 0) {
1122                         int32_t i;
1123                         struct phdr_desc *hdr;
1124                         struct part_desc *pdesc;
1125                         struct ud_part *pnew, *pold, *part;
1126 
1127                         pdesc = (struct part_desc *)ttag;
1128                         pold = udf_vfsp->udf_parts;
1129                         for (i = 0; i < udf_vfsp->udf_npart; i++) {
1130                                 if (pold->udp_number !=
1131                                     SWAP_16(pdesc->pd_pnum)) {
1132                                         pold++;
1133                                         continue;
1134                                 }
1135 
1136                                 if (SWAP_32(pdesc->pd_vdsn) >
1137                                     pold->udp_seqno) {
1138                                         pold->udp_seqno =
1139                                             SWAP_32(pdesc->pd_vdsn);
1140                                         pold->udp_access =
1141                                             SWAP_32(pdesc->pd_acc_type);
1142                                         pold->udp_start =
1143                                             SWAP_32(pdesc->pd_part_start);
1144                                         pold->udp_length =
1145                                             SWAP_32(pdesc->pd_part_length);
1146                                 }
1147                                 goto loop_end;
1148                         }


1149                         pold = udf_vfsp->udf_parts;
1150                         udf_vfsp->udf_npart++;
1151                         pnew = kmem_zalloc(udf_vfsp->udf_npart *
1152                             sizeof (struct ud_part), KM_SLEEP);
1153                         udf_vfsp->udf_parts = pnew;
1154                         if (pold) {
1155                                 bcopy(pold, pnew,
1156                                     sizeof (struct ud_part) *
1157                                     (udf_vfsp->udf_npart - 1));
1158                                 kmem_free(pold,
1159                                     sizeof (struct ud_part) *
1160                                     (udf_vfsp->udf_npart - 1));
1161                         }
1162                         part = pnew + (udf_vfsp->udf_npart - 1);
1163                         part->udp_number = SWAP_16(pdesc->pd_pnum);
1164                         part->udp_seqno = SWAP_32(pdesc->pd_vdsn);
1165                         part->udp_access = SWAP_32(pdesc->pd_acc_type);
1166                         part->udp_start = SWAP_32(pdesc->pd_part_start);
1167                         part->udp_length = SWAP_32(pdesc->pd_part_length);
1168                         part->udp_last_alloc = 0;


1265                             udf_vfsp->udf_parts[index].udp_access;
1266                 }
1267         }
1268         if ((udf_vfsp->udf_mtype < UDF_MT_RO) ||
1269             (udf_vfsp->udf_mtype > UDF_MT_OW)) {
1270                 udf_vfsp->udf_mtype = UDF_MT_RO;
1271         }
1272 
1273         udf_vfsp->udf_nmaps = 0;
1274         hdr = (struct pmap_hdr *)udf_vfsp->udf_lvd->lvd_pmaps;
1275         count = SWAP_32(udf_vfsp->udf_lvd->lvd_num_pmaps);
1276         for (index = 0; index < count; index++) {
1277 
1278                 if ((hdr->maph_type == MAP_TYPE1) &&
1279                     (hdr->maph_length == MAP_TYPE1_LEN)) {
1280                         typ1 = (struct pmap_typ1 *)hdr;
1281 
1282                         map = udf_vfsp->udf_maps;
1283                         udf_vfsp->udf_maps =
1284                             kmem_zalloc(sizeof (struct ud_map) *
1285                             (udf_vfsp->udf_nmaps + 1), KM_SLEEP);

1286                         if (map != NULL) {
1287                                 bcopy(map, udf_vfsp->udf_maps,
1288                                     sizeof (struct ud_map) *
1289                                     udf_vfsp->udf_nmaps);
1290                                 kmem_free(map, sizeof (struct ud_map) *
1291                                     udf_vfsp->udf_nmaps);
1292                         }
1293                         map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps;
1294                         map->udm_flags = UDM_MAP_NORM;
1295                         map->udm_vsn = SWAP_16(typ1->map1_vsn);
1296                         map->udm_pn = SWAP_16(typ1->map1_pn);
1297                         udf_vfsp->udf_nmaps ++;
1298                 } else if ((hdr->maph_type == MAP_TYPE2) &&
1299                     (hdr->maph_length == MAP_TYPE2_LEN)) {
1300                         typ2 = (struct pmap_typ2 *)hdr;
1301 
1302                         if (strncmp(typ2->map2_pti.reg_id,
1303                             UDF_VIRT_PART, 23) == 0) {
1304                                 /*
1305                                  * Add this to the normal
1306                                  * partition table so that
1307                                  * we donot
1308                                  */
1309                                 map = udf_vfsp->udf_maps;
1310                                 udf_vfsp->udf_maps =
1311                                     kmem_zalloc(sizeof (struct ud_map) *
1312                                     (udf_vfsp->udf_nmaps + 1), KM_SLEEP);

1313                                 if (map != NULL) {
1314                                         bcopy(map, udf_vfsp->udf_maps,
1315                                             sizeof (struct ud_map) *
1316                                             udf_vfsp->udf_nmaps);
1317                                         kmem_free(map,
1318                                             sizeof (struct ud_map) *
1319                                             udf_vfsp->udf_nmaps);
1320                                 }
1321                                 map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps;
1322                                 map->udm_flags = UDM_MAP_VPM;
1323                                 map->udm_vsn = SWAP_16(typ2->map2_vsn);
1324                                 map->udm_pn = SWAP_16(typ2->map2_pn);
1325                                 udf_vfsp->udf_nmaps ++;
1326                                 if (error = ud_get_last_block(dev, &lblkno)) {
1327                                         goto out;
1328                                 }
1329                                 if (error = ud_val_get_vat(udf_vfsp, dev,
1330                                     lblkno, map)) {
1331                                         goto out;
1332                                 }