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 }
|