Print this page
PSARC 2008/290 lofi mount
6384817 Need persistent lofi based mounts and direct mount(1m) support for lofi
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/udfs/udf_vfsops.c
+++ new/usr/src/uts/common/fs/udfs/udf_vfsops.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 - * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
22 + * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 -#pragma ident "@(#)udf_vfsops.c 1.48 07/10/25 SMI"
26 +#pragma ident "@(#)udf_vfsops.c 1.49 08/05/07 SMI"
27 27
28 28 #include <sys/types.h>
29 29 #include <sys/t_lock.h>
30 30 #include <sys/param.h>
31 31 #include <sys/time.h>
32 32 #include <sys/systm.h>
33 33 #include <sys/sysmacros.h>
34 34 #include <sys/resource.h>
35 35 #include <sys/signal.h>
36 36 #include <sys/cred.h>
37 37 #include <sys/user.h>
38 38 #include <sys/buf.h>
39 39 #include <sys/vfs.h>
40 40 #include <sys/vfs_opreg.h>
41 41 #include <sys/stat.h>
42 42 #include <sys/vnode.h>
43 43 #include <sys/mode.h>
44 44 #include <sys/proc.h>
45 45 #include <sys/disp.h>
46 46 #include <sys/file.h>
47 47 #include <sys/fcntl.h>
48 48 #include <sys/flock.h>
49 49 #include <sys/kmem.h>
50 50 #include <sys/uio.h>
51 51 #include <sys/dnlc.h>
52 52 #include <sys/conf.h>
53 53 #include <sys/errno.h>
54 54 #include <sys/mman.h>
55 55 #include <sys/fbuf.h>
56 56 #include <sys/pathname.h>
57 57 #include <sys/debug.h>
58 58 #include <sys/vmsystm.h>
59 59 #include <sys/cmn_err.h>
60 60 #include <sys/dirent.h>
61 61 #include <sys/errno.h>
62 62 #include <sys/modctl.h>
63 63 #include <sys/statvfs.h>
64 64 #include <sys/mount.h>
65 65 #include <sys/sunddi.h>
66 66 #include <sys/bootconf.h>
67 67 #include <sys/policy.h>
68 68
69 69 #include <vm/hat.h>
70 70 #include <vm/page.h>
71 71 #include <vm/pvn.h>
72 72 #include <vm/as.h>
73 73 #include <vm/seg.h>
74 74 #include <vm/seg_map.h>
75 75 #include <vm/seg_kmem.h>
76 76 #include <vm/seg_vn.h>
77 77 #include <vm/rm.h>
78 78 #include <vm/page.h>
79 79 #include <sys/swap.h>
80 80 #include <sys/mntent.h>
81 81
82 82
83 83 #include <fs/fs_subr.h>
|
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
84 84
85 85
86 86 #include <sys/fs/udf_volume.h>
87 87 #include <sys/fs/udf_inode.h>
88 88
89 89
90 90 extern struct vnode *common_specvp(struct vnode *vp);
91 91
92 92 extern kmutex_t ud_sync_busy;
93 93 static int32_t ud_mountfs(struct vfs *,
94 - enum whymountroot, dev_t, char *, struct cred *, int32_t);
94 + enum whymountroot, dev_t, char *, struct cred *, int32_t);
95 95 static struct udf_vfs *ud_validate_and_fill_superblock(dev_t,
96 - int32_t, uint32_t);
96 + int32_t, uint32_t);
97 97 void ud_destroy_fsp(struct udf_vfs *);
98 98 void ud_convert_to_superblock(struct udf_vfs *,
99 - struct log_vol_int_desc *);
99 + struct log_vol_int_desc *);
100 100 void ud_update_superblock(struct vfs *);
101 101 int32_t ud_get_last_block(dev_t, daddr_t *);
102 102 static int32_t ud_val_get_vat(struct udf_vfs *,
103 - dev_t, daddr_t, struct ud_map *);
103 + dev_t, daddr_t, struct ud_map *);
104 104 int32_t ud_read_sparing_tbls(struct udf_vfs *,
105 - dev_t, struct ud_map *, struct pmap_typ2 *);
105 + dev_t, struct ud_map *, struct pmap_typ2 *);
106 106 uint32_t ud_get_lbsize(dev_t, uint32_t *);
107 107
108 108 static int32_t udf_mount(struct vfs *,
109 - struct vnode *, struct mounta *, struct cred *);
109 + struct vnode *, struct mounta *, struct cred *);
110 110 static int32_t udf_unmount(struct vfs *, int, struct cred *);
111 111 static int32_t udf_root(struct vfs *, struct vnode **);
112 112 static int32_t udf_statvfs(struct vfs *, struct statvfs64 *);
113 113 static int32_t udf_sync(struct vfs *, int16_t, struct cred *);
114 114 static int32_t udf_vget(struct vfs *, struct vnode **, struct fid *);
115 115 static int32_t udf_mountroot(struct vfs *vfsp, enum whymountroot);
116 116
117 117 static int udfinit(int, char *);
118 118
119 119 static mntopts_t udfs_mntopts;
120 120
121 121 static vfsdef_t vfw = {
122 122 VFSDEF_VERSION,
123 123 "udfs",
124 124 udfinit,
125 125 VSW_HASPROTO|VSW_CANREMOUNT|VSW_STATS,
126 126 &udfs_mntopts
127 127 };
128 128
129 129 static mntopts_t udfs_mntopts = {
130 130 0,
131 131 NULL
132 132 };
133 133
134 134 /*
135 135 * Module linkage information for the kernel.
136 136 */
137 137 extern struct mod_ops mod_fsops;
138 138
139 139 static struct modlfs modlfs = {
140 140 &mod_fsops, "filesystem for UDFS", &vfw
141 141 };
142 142
143 143 static struct modlinkage modlinkage = {
144 144 MODREV_1, (void *)&modlfs, NULL
145 145 };
146 146
147 147 char _depends_on[] = "fs/specfs";
148 148
149 149 int32_t udf_fstype = -1;
150 150
151 151 int
152 152 _init()
153 153 {
154 154 return (mod_install(&modlinkage));
155 155 }
156 156
157 157 int
158 158 _fini()
159 159 {
160 160 return (EBUSY);
161 161 }
162 162
163 163 int
164 164 _info(struct modinfo *modinfop)
165 165 {
166 166 return (mod_info(&modlinkage, modinfop));
167 167 }
168 168
169 169
170 170 /* -------------------- vfs routines -------------------- */
171 171
172 172 /*
173 173 * XXX - this appears only to be used by the VM code to handle the case where
174 174 * UNIX is running off the mini-root. That probably wants to be done
175 175 * differently.
|
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
176 176 */
177 177 struct vnode *rootvp;
178 178 #ifndef __lint
179 179 _NOTE(SCHEME_PROTECTS_DATA("safe sharing", rootvp))
180 180 #endif
181 181 static int32_t
182 182 udf_mount(struct vfs *vfsp, struct vnode *mvp,
183 183 struct mounta *uap, struct cred *cr)
184 184 {
185 185 dev_t dev;
186 - struct vnode *bvp;
186 + struct vnode *lvp = NULL;
187 + struct vnode *svp = NULL;
187 188 struct pathname dpn;
188 189 int32_t error;
189 190 enum whymountroot why;
190 191 int oflag, aflag;
191 192
192 193 ud_printf("udf_mount\n");
193 194
194 195 if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0) {
195 196 return (error);
196 197 }
197 198
198 199 if (mvp->v_type != VDIR) {
199 200 return (ENOTDIR);
200 201 }
201 202
202 203 mutex_enter(&mvp->v_lock);
203 204 if ((uap->flags & MS_REMOUNT) == 0 &&
204 205 (uap->flags & MS_OVERLAY) == 0 &&
205 - (mvp->v_count != 1 || (mvp->v_flag & VROOT))) {
206 + (mvp->v_count != 1 || (mvp->v_flag & VROOT))) {
206 207 mutex_exit(&mvp->v_lock);
207 208 return (EBUSY);
208 209 }
209 210 mutex_exit(&mvp->v_lock);
210 211
211 212 if (error = pn_get(uap->dir, UIO_USERSPACE, &dpn)) {
212 213 return (error);
213 214 }
214 215
215 216 /*
216 - * Resolve path name of special file being mounted.
217 + * Resolve path name of the file being mounted.
217 218 */
218 219 if (error = lookupname(uap->spec, UIO_USERSPACE, FOLLOW, NULLVPP,
219 - &bvp)) {
220 + &svp)) {
220 221 pn_free(&dpn);
221 222 return (error);
222 223 }
223 - if (bvp->v_type != VBLK) {
224 - error = ENOTBLK;
224 +
225 + error = vfs_get_lofi(vfsp, &lvp);
226 +
227 + if (error > 0) {
228 + if (error == ENOENT)
229 + error = ENODEV;
225 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 + }
226 240 }
227 - dev = bvp->v_rdev;
228 241
229 242 /*
230 243 * Ensure that this device isn't already mounted,
231 244 * unless this is a REMOUNT request
232 245 */
233 246 if (vfs_devmounting(dev, vfsp)) {
234 247 error = EBUSY;
235 248 goto out;
236 249 }
237 250 if (vfs_devismounted(dev)) {
238 251 if (uap->flags & MS_REMOUNT) {
239 252 why = ROOT_REMOUNT;
240 253 } else {
241 254 error = EBUSY;
242 255 goto out;
243 256 }
244 257 } else {
245 258 why = ROOT_INIT;
246 259 }
247 260 if (getmajor(dev) >= devcnt) {
248 261 error = ENXIO;
249 262 goto out;
250 263 }
251 264
252 265 /*
253 266 * If the device is a tape, mount it read only
254 267 */
255 268 if (devopsp[getmajor(dev)]->devo_cb_ops->cb_flag & D_TAPE) {
256 269 vfsp->vfs_flag |= VFS_RDONLY;
257 270 }
258 271
259 272 if (uap->flags & MS_RDONLY) {
260 273 vfsp->vfs_flag |= VFS_RDONLY;
261 274 }
262 275
263 276 /*
264 277 * Set mount options.
265 278 */
266 279 if (uap->flags & MS_RDONLY) {
267 280 vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0);
268 281 }
269 282 if (uap->flags & MS_NOSUID) {
270 283 vfs_setmntopt(vfsp, MNTOPT_NOSUID, NULL, 0);
271 284 }
272 285
273 286 /*
274 287 * Verify that the caller can open the device special file as
|
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
275 288 * required. It is not until this moment that we know whether
276 289 * we're mounting "ro" or not.
277 290 */
278 291 if ((vfsp->vfs_flag & VFS_RDONLY) != 0) {
279 292 oflag = FREAD;
280 293 aflag = VREAD;
281 294 } else {
282 295 oflag = FREAD | FWRITE;
283 296 aflag = VREAD | VWRITE;
284 297 }
285 - if ((error = VOP_ACCESS(bvp, aflag, 0, cr, NULL)) != 0 ||
286 - (error = secpolicy_spec_open(cr, bvp, oflag)) != 0) {
298 +
299 + if (lvp == NULL &&
300 + (error = secpolicy_spec_open(cr, svp, oflag)) != 0)
287 301 goto out;
288 - }
289 302
303 + if ((error = VOP_ACCESS(svp, aflag, 0, cr, NULL)) != 0)
304 + goto out;
305 +
290 306 /*
291 307 * Mount the filesystem.
292 308 */
293 309 error = ud_mountfs(vfsp, why, dev, dpn.pn_path, cr, 0);
294 310 out:
295 - VN_RELE(bvp);
311 + if (svp != NULL)
312 + VN_RELE(svp);
313 + if (lvp != NULL)
314 + VN_RELE(lvp);
296 315 pn_free(&dpn);
297 -
298 316 return (error);
299 317 }
300 318
301 319
302 320
303 321 /*
304 322 * unmount the file system pointed
305 323 * by vfsp
306 324 */
307 325 /* ARGSUSED */
308 326 static int32_t
309 327 udf_unmount(struct vfs *vfsp, int fflag, struct cred *cr)
310 328 {
311 329 struct udf_vfs *udf_vfsp;
312 330 struct vnode *bvp, *rvp;
313 331 struct ud_inode *rip;
314 332 int32_t flag;
315 333
316 334 ud_printf("udf_unmount\n");
317 335
318 336 if (secpolicy_fs_unmount(cr, vfsp) != 0) {
319 337 return (EPERM);
320 338 }
321 339
322 340 /*
323 341 * forced unmount is not supported by this file system
324 342 * and thus, ENOTSUP, is being returned.
325 343 */
326 344 if (fflag & MS_FORCE)
327 345 return (ENOTSUP);
328 346
329 347 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data;
330 348 flag = !(udf_vfsp->udf_flags & UDF_FL_RDONLY);
331 349 bvp = udf_vfsp->udf_devvp;
332 350
333 351 rvp = udf_vfsp->udf_root;
334 352 ASSERT(rvp != NULL);
335 353 rip = VTOI(rvp);
336 354
337 355 (void) ud_release_cache(udf_vfsp);
338 356
339 357
340 358 /* Flush all inodes except root */
341 359 if (ud_iflush(vfsp) < 0) {
342 360 return (EBUSY);
343 361 }
344 362
345 363 rw_enter(&rip->i_contents, RW_WRITER);
346 364 (void) ud_syncip(rip, B_INVAL, I_SYNC);
347 365 rw_exit(&rip->i_contents);
348 366
349 367 mutex_enter(&ud_sync_busy);
350 368 if ((udf_vfsp->udf_flags & UDF_FL_RDONLY) == 0) {
351 369 bflush(vfsp->vfs_dev);
352 370 mutex_enter(&udf_vfsp->udf_lock);
353 371 udf_vfsp->udf_clean = UDF_CLEAN;
354 372 mutex_exit(&udf_vfsp->udf_lock);
355 373 ud_update_superblock(vfsp);
356 374 }
357 375 mutex_exit(&ud_sync_busy);
358 376
359 377 mutex_destroy(&udf_vfsp->udf_lock);
360 378 mutex_destroy(&udf_vfsp->udf_rename_lck);
361 379
362 380 ud_delcache(rip);
363 381 ITIMES(rip);
364 382 VN_RELE(rvp);
365 383
366 384 ud_destroy_fsp(udf_vfsp);
367 385
368 386 (void) VOP_PUTPAGE(bvp, (offset_t)0, (uint32_t)0, B_INVAL, cr, NULL);
369 387 (void) VOP_CLOSE(bvp, flag, 1, (offset_t)0, cr, NULL);
370 388
371 389 (void) bfinval(vfsp->vfs_dev, 1);
372 390 VN_RELE(bvp);
373 391
374 392
375 393 return (0);
376 394 }
377 395
378 396
379 397 /*
380 398 * Get the root vp for the
381 399 * file system
382 400 */
383 401 static int32_t
384 402 udf_root(struct vfs *vfsp, struct vnode **vpp)
385 403 {
386 404 struct udf_vfs *udf_vfsp;
387 405 struct vnode *vp;
388 406
389 407 ud_printf("udf_root\n");
390 408
391 409 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data;
392 410
393 411 ASSERT(udf_vfsp != NULL);
394 412 ASSERT(udf_vfsp->udf_root != NULL);
395 413
396 414 vp = udf_vfsp->udf_root;
397 415 VN_HOLD(vp);
398 416 *vpp = vp;
399 417 return (0);
400 418 }
401 419
402 420
403 421 /*
404 422 * Get file system statistics.
405 423 */
406 424 static int32_t
407 425 udf_statvfs(struct vfs *vfsp, struct statvfs64 *sp)
408 426 {
409 427 struct udf_vfs *udf_vfsp;
410 428 struct ud_part *parts;
411 429 dev32_t d32;
412 430 int32_t index;
413 431
414 432 ud_printf("udf_statvfs\n");
415 433
416 434 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data;
417 435 (void) bzero(sp, sizeof (struct statvfs64));
418 436
419 437 mutex_enter(&udf_vfsp->udf_lock);
420 438 sp->f_bsize = udf_vfsp->udf_lbsize;
421 439 sp->f_frsize = udf_vfsp->udf_lbsize;
422 440 sp->f_blocks = 0;
423 441 sp->f_bfree = 0;
424 442 parts = udf_vfsp->udf_parts;
425 443 for (index = 0; index < udf_vfsp->udf_npart; index++) {
426 444 sp->f_blocks += parts->udp_nblocks;
427 445 sp->f_bfree += parts->udp_nfree;
428 446 parts++;
|
↓ open down ↓ |
121 lines elided |
↑ open up ↑ |
429 447 }
430 448 sp->f_bavail = sp->f_bfree;
431 449
432 450 /*
433 451 * Since there are no real inodes allocated
434 452 * we will approximate
435 453 * each new file will occupy :
436 454 * 38(over head each dent) + MAXNAMLEN / 2 + inode_size(==block size)
437 455 */
438 456 sp->f_ffree = sp->f_favail =
439 - (sp->f_bavail * sp->f_bsize) / (146 + sp->f_bsize);
457 + (sp->f_bavail * sp->f_bsize) / (146 + sp->f_bsize);
440 458
441 459 /*
442 460 * The total number of inodes is
443 461 * the sum of files + directories + free inodes
444 462 */
445 - sp->f_files = sp->f_ffree +
446 - udf_vfsp->udf_nfiles +
447 - udf_vfsp->udf_ndirs;
463 + sp->f_files = sp->f_ffree + udf_vfsp->udf_nfiles + udf_vfsp->udf_ndirs;
448 464 (void) cmpldev(&d32, vfsp->vfs_dev);
449 465 sp->f_fsid = d32;
450 466 (void) strcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name);
451 467 sp->f_flag = vf_to_stf(vfsp->vfs_flag);
452 468 sp->f_namemax = MAXNAMLEN;
453 469 (void) strcpy(sp->f_fstr, udf_vfsp->udf_volid);
454 470
455 471 mutex_exit(&udf_vfsp->udf_lock);
456 472
457 473 return (0);
458 474 }
459 475
460 476
461 477 /*
462 478 * Flush any pending I/O to file system vfsp.
463 479 * The ud_update() routine will only flush *all* udf files.
464 480 */
465 481 /*ARGSUSED*/
466 482 /* ARGSUSED */
467 483 static int32_t
468 484 udf_sync(struct vfs *vfsp, int16_t flag, struct cred *cr)
469 485 {
470 486 ud_printf("udf_sync\n");
471 487
472 488 ud_update(flag);
473 489 return (0);
474 490 }
475 491
476 492
477 493
478 494 /* ARGSUSED */
479 495 static int32_t
480 496 udf_vget(struct vfs *vfsp,
481 497 struct vnode **vpp, struct fid *fidp)
482 498 {
483 499 int32_t error = 0;
484 500 struct udf_fid *udfid;
485 501 struct udf_vfs *udf_vfsp;
486 502 struct ud_inode *ip;
487 503
|
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
488 504 ud_printf("udf_vget\n");
489 505
490 506 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data;
491 507 if (udf_vfsp == NULL) {
492 508 *vpp = NULL;
493 509 return (0);
494 510 }
495 511
496 512 udfid = (struct udf_fid *)fidp;
497 513 if ((error = ud_iget(vfsp, udfid->udfid_prn,
498 - udfid->udfid_icb_lbn, &ip, NULL, CRED())) != 0) {
514 + udfid->udfid_icb_lbn, &ip, NULL, CRED())) != 0) {
499 515 *vpp = NULL;
500 516 return (error);
501 517 }
502 518
503 519 rw_enter(&ip->i_contents, RW_READER);
504 520 if ((udfid->udfid_uinq_lo != (ip->i_uniqid & 0xffffffff)) ||
505 - (udfid->udfid_prn != ip->i_icb_prn)) {
521 + (udfid->udfid_prn != ip->i_icb_prn)) {
506 522 rw_exit(&ip->i_contents);
507 523 VN_RELE(ITOV(ip));
508 524 *vpp = NULL;
509 525 return (EINVAL);
510 526 }
511 527 rw_exit(&ip->i_contents);
512 528
513 529 *vpp = ITOV(ip);
514 530 return (0);
515 531 }
516 532
517 533
518 534 /*
519 535 * Mount root file system.
520 536 * "why" is ROOT_INIT on initial call, ROOT_REMOUNT if called to
521 537 * remount the root file system, and ROOT_UNMOUNT if called to
522 538 * unmount the root (e.g., as part of a system shutdown).
523 539 *
524 540 * XXX - this may be partially machine-dependent; it, along with the VFS_SWAPVP
525 541 * operation, goes along with auto-configuration. A mechanism should be
526 542 * provided by which machine-INdependent code in the kernel can say "get me the
527 543 * right root file system" and "get me the right initial swap area", and have
528 544 * that done in what may well be a machine-dependent fashion.
529 545 * Unfortunately, it is also file-system-type dependent (NFS gets it via
530 546 * bootparams calls, UFS gets it from various and sundry machine-dependent
531 547 * mechanisms, as SPECFS does for swap).
532 548 */
533 549 /* ARGSUSED */
534 550 static int32_t
535 551 udf_mountroot(struct vfs *vfsp, enum whymountroot why)
536 552 {
537 553 dev_t rootdev;
538 554 static int32_t udf_rootdone = 0;
539 555 struct vnode *vp = NULL;
540 556 int32_t ovflags, error;
541 557 ud_printf("udf_mountroot\n");
542 558
543 559 if (why == ROOT_INIT) {
544 560 if (udf_rootdone++) {
545 561 return (EBUSY);
546 562 }
547 563 rootdev = getrootdev();
|
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
548 564 if (rootdev == (dev_t)NODEV) {
549 565 return (ENODEV);
550 566 }
551 567 vfsp->vfs_dev = rootdev;
552 568 vfsp->vfs_flag |= VFS_RDONLY;
553 569 } else if (why == ROOT_REMOUNT) {
554 570 vp = ((struct udf_vfs *)vfsp->vfs_data)->udf_devvp;
555 571 (void) dnlc_purge_vfsp(vfsp, 0);
556 572 vp = common_specvp(vp);
557 573 (void) VOP_PUTPAGE(vp, (offset_t)0,
558 - (uint32_t)0, B_INVAL, CRED(), NULL);
574 + (uint32_t)0, B_INVAL, CRED(), NULL);
559 575 binval(vfsp->vfs_dev);
560 576
561 577 ovflags = vfsp->vfs_flag;
562 578 vfsp->vfs_flag &= ~VFS_RDONLY;
563 579 vfsp->vfs_flag |= VFS_REMOUNT;
564 580 rootdev = vfsp->vfs_dev;
565 581 } else if (why == ROOT_UNMOUNT) {
566 582 ud_update(0);
567 583 vp = ((struct udf_vfs *)vfsp->vfs_data)->udf_devvp;
568 584 (void) VOP_CLOSE(vp, FREAD|FWRITE, 1,
569 - (offset_t)0, CRED(), NULL);
585 + (offset_t)0, CRED(), NULL);
570 586 return (0);
571 587 }
572 588
573 589 if ((error = vfs_lock(vfsp)) != 0) {
574 590 return (error);
575 591 }
576 592
577 593 error = ud_mountfs(vfsp, why, rootdev, "/", CRED(), 1);
578 594 if (error) {
579 595 vfs_unlock(vfsp);
580 596 if (why == ROOT_REMOUNT) {
581 597 vfsp->vfs_flag = ovflags;
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
582 598 }
583 599 if (rootvp) {
584 600 VN_RELE(rootvp);
585 601 rootvp = (struct vnode *)0;
586 602 }
587 603 return (error);
588 604 }
589 605
590 606 if (why == ROOT_INIT) {
591 607 vfs_add((struct vnode *)0, vfsp,
592 - (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0);
608 + (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0);
593 609 }
594 610 vfs_unlock(vfsp);
595 611 return (0);
596 612 }
597 613
598 614
599 615 /* ------------------------- local routines ------------------------- */
600 616
601 617
602 618 static int32_t
603 619 ud_mountfs(struct vfs *vfsp,
604 620 enum whymountroot why, dev_t dev, char *name,
605 621 struct cred *cr, int32_t isroot)
606 622 {
607 623 struct vnode *devvp = NULL;
608 624 int32_t error = 0;
609 625 int32_t needclose = 0;
610 626 struct udf_vfs *udf_vfsp = NULL;
611 627 struct log_vol_int_desc *lvid;
612 628 struct ud_inode *rip = NULL;
613 629 struct vnode *rvp = NULL;
614 630 int32_t i, lbsize;
615 631 uint32_t avd_loc;
616 632 struct ud_map *map;
617 633 int32_t desc_len;
618 634
619 635 ud_printf("ud_mountfs\n");
620 636
621 637 if (why == ROOT_INIT) {
622 638 /*
623 639 * Open the device.
624 640 */
625 641 devvp = makespecvp(dev, VBLK);
626 642
627 643 /*
628 644 * Open block device mounted on.
629 645 * When bio is fixed for vnodes this can all be vnode
630 646 * operations.
631 647 */
632 648 error = VOP_OPEN(&devvp,
633 649 (vfsp->vfs_flag & VFS_RDONLY) ? FREAD : FREAD|FWRITE,
634 650 cr, NULL);
635 651 if (error) {
636 652 goto out;
637 653 }
638 654 needclose = 1;
639 655
640 656 /*
641 657 * Refuse to go any further if this
642 658 * device is being used for swapping.
643 659 */
644 660 if (IS_SWAPVP(devvp)) {
645 661 error = EBUSY;
646 662 goto out;
647 663 }
648 664 }
649 665
650 666 /*
651 667 * check for dev already mounted on
652 668 */
653 669 if (vfsp->vfs_flag & VFS_REMOUNT) {
654 670 struct tag *ttag;
655 671 int32_t index, count;
656 672 struct buf *tpt = 0;
657 673 caddr_t addr;
658 674
659 675
660 676 /* cannot remount to RDONLY */
661 677 if (vfsp->vfs_flag & VFS_RDONLY) {
662 678 return (EINVAL);
663 679 }
664 680
665 681 if (vfsp->vfs_dev != dev) {
666 682 return (EINVAL);
667 683 }
668 684
669 685 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data;
670 686 devvp = udf_vfsp->udf_devvp;
|
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
671 687
672 688 /*
673 689 * fsck may have altered the file system; discard
674 690 * as much incore data as possible. Don't flush
675 691 * if this is a rw to rw remount; it's just resetting
676 692 * the options.
677 693 */
678 694 if (udf_vfsp->udf_flags & UDF_FL_RDONLY) {
679 695 (void) dnlc_purge_vfsp(vfsp, 0);
680 696 (void) VOP_PUTPAGE(devvp, (offset_t)0, (uint_t)0,
681 - B_INVAL, CRED(), NULL);
697 + B_INVAL, CRED(), NULL);
682 698 (void) ud_iflush(vfsp);
683 699 bflush(dev);
684 700 binval(dev);
685 701 }
686 702
687 703 /*
688 704 * We could read UDF1.50 and write UDF1.50 only
689 705 * disallow mount of any highier version
690 706 */
691 707 if ((udf_vfsp->udf_miread > UDF_150) ||
692 - (udf_vfsp->udf_miwrite > UDF_150)) {
708 + (udf_vfsp->udf_miwrite > UDF_150)) {
693 709 error = EINVAL;
694 710 goto remountout;
695 711 }
696 712
697 713 /*
698 714 * read/write to read/write; all done
699 715 */
700 716 if (udf_vfsp->udf_flags & UDF_FL_RW) {
701 717 goto remountout;
702 718 }
703 719
704 720 /*
705 721 * Does the media type allow a writable mount
706 722 */
707 723 if (udf_vfsp->udf_mtype != UDF_MT_OW) {
|
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
708 724 error = EINVAL;
709 725 goto remountout;
710 726 }
711 727
712 728 /*
713 729 * Read the metadata
714 730 * and check if it is possible to
715 731 * mount in rw mode
716 732 */
717 733 tpt = ud_bread(vfsp->vfs_dev,
718 - udf_vfsp->udf_iseq_loc << udf_vfsp->udf_l2d_shift,
719 - udf_vfsp->udf_iseq_len);
734 + udf_vfsp->udf_iseq_loc << udf_vfsp->udf_l2d_shift,
735 + udf_vfsp->udf_iseq_len);
720 736 if (tpt->b_flags & B_ERROR) {
721 737 error = EIO;
722 738 goto remountout;
723 739 }
724 740 count = udf_vfsp->udf_iseq_len / DEV_BSIZE;
725 741 addr = tpt->b_un.b_addr;
726 742 for (index = 0; index < count; index ++) {
727 743 ttag = (struct tag *)(addr + index * DEV_BSIZE);
728 744 desc_len = udf_vfsp->udf_iseq_len - (index * DEV_BSIZE);
729 745 if (ud_verify_tag_and_desc(ttag, UD_LOG_VOL_INT,
730 746 udf_vfsp->udf_iseq_loc +
731 747 (index >> udf_vfsp->udf_l2d_shift),
732 748 1, desc_len) == 0) {
733 749 struct log_vol_int_desc *lvid;
734 750
735 751 lvid = (struct log_vol_int_desc *)ttag;
736 752
737 753 if (SWAP_32(lvid->lvid_int_type) !=
738 - LOG_VOL_CLOSE_INT) {
754 + LOG_VOL_CLOSE_INT) {
739 755 error = EINVAL;
740 756 goto remountout;
741 757 }
742 758
743 759 /*
744 760 * Copy new data to old data
745 761 */
746 762 bcopy(udf_vfsp->udf_iseq->b_un.b_addr,
747 - tpt->b_un.b_addr, udf_vfsp->udf_iseq_len);
763 + tpt->b_un.b_addr, udf_vfsp->udf_iseq_len);
748 764 break;
749 765 }
750 766 }
751 767
752 768 udf_vfsp->udf_flags = UDF_FL_RW;
753 769
754 770 mutex_enter(&udf_vfsp->udf_lock);
755 771 ud_sbwrite(udf_vfsp);
756 772 mutex_exit(&udf_vfsp->udf_lock);
757 773 remountout:
758 774 if (tpt != NULL) {
759 775 tpt->b_flags = B_AGE | B_STALE;
760 776 brelse(tpt);
761 777 }
762 778 return (error);
763 779 }
764 780
765 781 ASSERT(devvp != 0);
766 782 /*
767 783 * Flush back any dirty pages on the block device to
768 784 * try and keep the buffer cache in sync with the page
769 785 * cache if someone is trying to use block devices when
770 786 * they really should be using the raw device.
771 787 */
772 788 (void) VOP_PUTPAGE(common_specvp(devvp), (offset_t)0,
773 789 (uint32_t)0, B_INVAL, cr, NULL);
774 790
775 791
776 792 /*
777 793 * Check if the file system
778 794 * is a valid udfs and fill
779 795 * the required fields in udf_vfs
780 796 */
781 797 #ifndef __lint
782 798 _NOTE(NO_COMPETING_THREADS_NOW);
783 799 #endif
784 800
785 801 if ((lbsize = ud_get_lbsize(dev, &avd_loc)) == 0) {
786 802 error = EINVAL;
787 803 goto out;
788 804 }
789 805
790 806 udf_vfsp = ud_validate_and_fill_superblock(dev, lbsize, avd_loc);
791 807 if (udf_vfsp == NULL) {
792 808 error = EINVAL;
793 809 goto out;
794 810 }
795 811
796 812 /*
797 813 * Fill in vfs private data
798 814 */
799 815 vfsp->vfs_fstype = udf_fstype;
800 816 vfs_make_fsid(&vfsp->vfs_fsid, dev, udf_fstype);
801 817 vfsp->vfs_data = (caddr_t)udf_vfsp;
802 818 vfsp->vfs_dev = dev;
803 819 vfsp->vfs_flag |= VFS_NOTRUNC;
804 820 udf_vfsp->udf_devvp = devvp;
805 821
806 822 udf_vfsp->udf_fsmnt = kmem_zalloc(strlen(name) + 1, KM_SLEEP);
807 823 (void) strcpy(udf_vfsp->udf_fsmnt, name);
808 824
809 825 udf_vfsp->udf_vfs = vfsp;
810 826 udf_vfsp->udf_rdclustsz = udf_vfsp->udf_wrclustsz = maxphys;
811 827
812 828 udf_vfsp->udf_mod = 0;
813 829
814 830
815 831 lvid = udf_vfsp->udf_lvid;
816 832 if (vfsp->vfs_flag & VFS_RDONLY) {
817 833 /*
818 834 * We could read only UDF1.50
819 835 * disallow mount of any highier version
820 836 */
821 837 if (udf_vfsp->udf_miread > UDF_150) {
822 838 error = EINVAL;
823 839 goto out;
824 840 }
825 841 udf_vfsp->udf_flags = UDF_FL_RDONLY;
826 842 if (SWAP_32(lvid->lvid_int_type) == LOG_VOL_CLOSE_INT) {
827 843 udf_vfsp->udf_clean = UDF_CLEAN;
828 844 } else {
829 845 /* Do we have a VAT at the end of the recorded media */
830 846 map = udf_vfsp->udf_maps;
831 847 for (i = 0; i < udf_vfsp->udf_nmaps; i++) {
832 848 if (map->udm_flags & UDM_MAP_VPM) {
833 849 break;
834 850 }
835 851 map++;
836 852 }
837 853 if (i == udf_vfsp->udf_nmaps) {
838 854 error = ENOSPC;
|
↓ open down ↓ |
81 lines elided |
↑ open up ↑ |
839 855 goto out;
840 856 }
841 857 udf_vfsp->udf_clean = UDF_CLEAN;
842 858 }
843 859 } else {
844 860 /*
845 861 * We could read UDF1.50 and write UDF1.50 only
846 862 * disallow mount of any highier version
847 863 */
848 864 if ((udf_vfsp->udf_miread > UDF_150) ||
849 - (udf_vfsp->udf_miwrite > UDF_150)) {
865 + (udf_vfsp->udf_miwrite > UDF_150)) {
850 866 error = EINVAL;
851 867 goto out;
852 868 }
853 869 /*
854 870 * Check if the media allows
855 871 * us to mount read/write
856 872 */
857 873 if (udf_vfsp->udf_mtype != UDF_MT_OW) {
858 874 error = EACCES;
859 875 goto out;
860 876 }
861 877
862 878 /*
863 879 * Check if we have VAT on a writable media
864 880 * we cannot use the media in presence of VAT
865 881 * Dent RW mount.
866 882 */
867 883 map = udf_vfsp->udf_maps;
868 884 ASSERT(map != NULL);
869 885 for (i = 0; i < udf_vfsp->udf_nmaps; i++) {
870 886 if (map->udm_flags & UDM_MAP_VPM) {
871 887 error = EACCES;
872 888 goto out;
873 889 }
874 890 map++;
875 891 }
876 892
877 893 /*
878 894 * Check if the domain Id allows
879 895 * us to write
880 896 */
881 897 if (udf_vfsp->udf_lvd->lvd_dom_id.reg_ids[2] & 0x3) {
882 898 error = EACCES;
883 899 goto out;
884 900 }
885 901 udf_vfsp->udf_flags = UDF_FL_RW;
886 902
887 903 if (SWAP_32(lvid->lvid_int_type) == LOG_VOL_CLOSE_INT) {
888 904 udf_vfsp->udf_clean = UDF_CLEAN;
889 905 } else {
890 906 if (isroot) {
891 907 udf_vfsp->udf_clean = UDF_DIRTY;
892 908 } else {
893 909 error = ENOSPC;
894 910 goto out;
895 911 }
896 912 }
|
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
897 913 }
898 914
899 915 mutex_init(&udf_vfsp->udf_lock, NULL, MUTEX_DEFAULT, NULL);
900 916
901 917 mutex_init(&udf_vfsp->udf_rename_lck, NULL, MUTEX_DEFAULT, NULL);
902 918
903 919 #ifndef __lint
904 920 _NOTE(COMPETING_THREADS_NOW);
905 921 #endif
906 922 if (error = ud_iget(vfsp, udf_vfsp->udf_ricb_prn,
907 - udf_vfsp->udf_ricb_loc, &rip, NULL, cr)) {
923 + udf_vfsp->udf_ricb_loc, &rip, NULL, cr)) {
908 924 mutex_destroy(&udf_vfsp->udf_lock);
909 925 goto out;
910 926 }
911 927
912 928
913 929 /*
914 930 * Get the root inode and
915 931 * initialize the root vnode
916 932 */
917 933 rvp = ITOV(rip);
918 934 mutex_enter(&rvp->v_lock);
919 935 rvp->v_flag |= VROOT;
920 936 mutex_exit(&rvp->v_lock);
921 937 udf_vfsp->udf_root = rvp;
922 938
923 939
924 940 if (why == ROOT_INIT && isroot)
925 941 rootvp = devvp;
926 942
927 943 ud_vfs_add(udf_vfsp);
928 944
929 945 if (udf_vfsp->udf_flags == UDF_FL_RW) {
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
930 946 udf_vfsp->udf_clean = UDF_DIRTY;
931 947 ud_update_superblock(vfsp);
932 948 }
933 949
934 950 return (0);
935 951
936 952 out:
937 953 ud_destroy_fsp(udf_vfsp);
938 954 if (needclose) {
939 955 (void) VOP_CLOSE(devvp, (vfsp->vfs_flag & VFS_RDONLY) ?
940 - FREAD : FREAD|FWRITE, 1, (offset_t)0, cr, NULL);
956 + FREAD : FREAD|FWRITE, 1, (offset_t)0, cr, NULL);
941 957 bflush(dev);
942 958 binval(dev);
943 959 }
944 960 VN_RELE(devvp);
945 961
946 962 return (error);
947 963 }
948 964
949 965
950 966 static struct udf_vfs *
951 967 ud_validate_and_fill_superblock(dev_t dev, int32_t bsize, uint32_t avd_loc)
952 968 {
953 969 int32_t error, count, index, shift;
954 970 uint32_t dummy, vds_loc;
955 971 caddr_t addr;
956 972 daddr_t blkno, lblkno;
957 973 struct buf *secbp, *bp;
958 974 struct tag *ttag;
959 975 struct anch_vol_desc_ptr *avdp;
960 976 struct file_set_desc *fsd;
961 977 struct udf_vfs *udf_vfsp = NULL;
962 978 struct pmap_hdr *hdr;
963 979 struct pmap_typ1 *typ1;
964 980 struct pmap_typ2 *typ2;
965 981 struct ud_map *map;
966 982 int32_t desc_len;
967 983
968 984 ud_printf("ud_validate_and_fill_superblock\n");
969 985
970 986 if (bsize < DEV_BSIZE) {
971 987 return (NULL);
972 988 }
973 989 shift = 0;
974 990 while ((bsize >> shift) > DEV_BSIZE) {
|
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
975 991 shift++;
976 992 }
977 993
978 994 /*
979 995 * Read Anchor Volume Descriptor
980 996 * Verify it and get the location of
981 997 * Main Volume Descriptor Sequence
982 998 */
983 999 secbp = ud_bread(dev, avd_loc << shift, ANCHOR_VOL_DESC_LEN);
984 1000 if ((error = geterror(secbp)) != 0) {
985 - cmn_err(CE_NOTE,
986 - "udfs : Could not read Anchor Volume Desc %x", error);
1001 + cmn_err(CE_NOTE, "udfs : Could not read Anchor Volume Desc %x",
1002 + error);
987 1003 brelse(secbp);
988 1004 return (NULL);
989 1005 }
990 1006 avdp = (struct anch_vol_desc_ptr *)secbp->b_un.b_addr;
991 1007 if (ud_verify_tag_and_desc(&avdp->avd_tag, UD_ANCH_VOL_DESC,
992 1008 avd_loc, 1, ANCHOR_VOL_DESC_LEN) != 0) {
993 1009 brelse(secbp);
994 1010 return (NULL);
995 1011 }
996 1012 udf_vfsp = (struct udf_vfs *)
997 - kmem_zalloc(sizeof (struct udf_vfs), KM_SLEEP);
1013 + kmem_zalloc(sizeof (struct udf_vfs), KM_SLEEP);
998 1014 udf_vfsp->udf_mvds_loc = SWAP_32(avdp->avd_main_vdse.ext_loc);
999 1015 udf_vfsp->udf_mvds_len = SWAP_32(avdp->avd_main_vdse.ext_len);
1000 1016 udf_vfsp->udf_rvds_loc = SWAP_32(avdp->avd_res_vdse.ext_loc);
1001 1017 udf_vfsp->udf_rvds_len = SWAP_32(avdp->avd_res_vdse.ext_len);
1002 1018 secbp->b_flags = B_AGE | B_STALE;
1003 1019 brelse(secbp);
1004 1020
1005 1021 /*
1006 1022 * Read Main Volume Descriptor Sequence
1007 1023 * and process it
1008 1024 */
1009 1025 vds_loc = udf_vfsp->udf_mvds_loc;
1010 1026 secbp = ud_bread(dev, vds_loc << shift,
1011 - udf_vfsp->udf_mvds_len);
1027 + udf_vfsp->udf_mvds_len);
1012 1028 if ((error = geterror(secbp)) != 0) {
1013 1029 brelse(secbp);
1014 - cmn_err(CE_NOTE,
1015 - "udfs : Could not read Main Volume Desc %x", error);
1030 + cmn_err(CE_NOTE, "udfs : Could not read Main Volume Desc %x",
1031 + error);
1016 1032
1017 1033 vds_loc = udf_vfsp->udf_rvds_loc;
1018 1034 secbp = ud_bread(dev, vds_loc << shift,
1019 - udf_vfsp->udf_rvds_len);
1035 + udf_vfsp->udf_rvds_len);
1020 1036 if ((error = geterror(secbp)) != 0) {
1021 1037 brelse(secbp);
1022 1038 cmn_err(CE_NOTE,
1023 1039 "udfs : Could not read Res Volume Desc %x", error);
1024 1040 return (NULL);
1025 1041 }
1026 1042 }
1027 1043
1028 1044 udf_vfsp->udf_vds = ngeteblk(udf_vfsp->udf_mvds_len);
1029 1045 bp = udf_vfsp->udf_vds;
1030 1046 bp->b_edev = dev;
1031 1047 bp->b_dev = cmpdev(dev);
1032 1048 bp->b_blkno = vds_loc << shift;
1033 1049 bp->b_bcount = udf_vfsp->udf_mvds_len;
1034 1050 bcopy(secbp->b_un.b_addr, bp->b_un.b_addr, udf_vfsp->udf_mvds_len);
1035 1051 secbp->b_flags |= B_STALE | B_AGE;
1036 1052 brelse(secbp);
1037 1053
1038 1054
|
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
1039 1055 count = udf_vfsp->udf_mvds_len / DEV_BSIZE;
1040 1056 addr = bp->b_un.b_addr;
1041 1057 for (index = 0; index < count; index ++) {
1042 1058 ttag = (struct tag *)(addr + index * DEV_BSIZE);
1043 1059 desc_len = udf_vfsp->udf_mvds_len - (index * DEV_BSIZE);
1044 1060 if (ud_verify_tag_and_desc(ttag, UD_PRI_VOL_DESC,
1045 1061 vds_loc + (index >> shift),
1046 1062 1, desc_len) == 0) {
1047 1063 if (udf_vfsp->udf_pvd == NULL) {
1048 1064 udf_vfsp->udf_pvd =
1049 - (struct pri_vol_desc *)ttag;
1065 + (struct pri_vol_desc *)ttag;
1050 1066 } else {
1051 1067 struct pri_vol_desc *opvd, *npvd;
1052 1068
1053 1069 opvd = udf_vfsp->udf_pvd;
1054 1070 npvd = (struct pri_vol_desc *)ttag;
1055 1071
1056 1072 if ((strncmp(opvd->pvd_vsi,
1057 - npvd->pvd_vsi, 128) == 0) &&
1058 - (strncmp(opvd->pvd_vol_id,
1059 - npvd->pvd_vol_id, 32) == 0) &&
1060 - (strncmp((caddr_t)&opvd->pvd_desc_cs,
1061 - (caddr_t)&npvd->pvd_desc_cs,
1062 - sizeof (charspec_t)) == 0)) {
1073 + npvd->pvd_vsi, 128) == 0) &&
1074 + (strncmp(opvd->pvd_vol_id,
1075 + npvd->pvd_vol_id, 32) == 0) &&
1076 + (strncmp((caddr_t)&opvd->pvd_desc_cs,
1077 + (caddr_t)&npvd->pvd_desc_cs,
1078 + sizeof (charspec_t)) == 0)) {
1063 1079
1064 1080 if (SWAP_32(opvd->pvd_vdsn) <
1065 - SWAP_32(npvd->pvd_vdsn)) {
1081 + SWAP_32(npvd->pvd_vdsn)) {
1066 1082 udf_vfsp->udf_pvd = npvd;
1067 1083 }
1068 1084 } else {
1069 1085 goto out;
1070 1086 }
1071 1087 }
1072 1088 } else if (ud_verify_tag_and_desc(ttag, UD_LOG_VOL_DESC,
1073 1089 vds_loc + (index >> shift),
1074 1090 1, desc_len) == 0) {
1075 1091 struct log_vol_desc *lvd;
1076 1092
1077 1093 lvd = (struct log_vol_desc *)ttag;
1078 1094 if (strncmp(lvd->lvd_dom_id.reg_id,
1079 - UDF_DOMAIN_NAME, 23) != 0) {
1095 + UDF_DOMAIN_NAME, 23) != 0) {
1080 1096 printf("Domain ID in lvd is not valid\n");
1081 1097 goto out;
1082 1098 }
1083 1099
1084 1100 if (udf_vfsp->udf_lvd == NULL) {
1085 1101 udf_vfsp->udf_lvd = lvd;
1086 1102 } else {
1087 1103 struct log_vol_desc *olvd;
1088 1104
1089 1105 olvd = udf_vfsp->udf_lvd;
1090 1106 if ((strncmp((caddr_t)&olvd->lvd_desc_cs,
1091 - (caddr_t)&lvd->lvd_desc_cs,
1092 - sizeof (charspec_t)) == 0) &&
1093 - (strncmp(olvd->lvd_lvid,
1094 - lvd->lvd_lvid, 128) == 0)) {
1107 + (caddr_t)&lvd->lvd_desc_cs,
1108 + sizeof (charspec_t)) == 0) &&
1109 + (strncmp(olvd->lvd_lvid,
1110 + lvd->lvd_lvid, 128) == 0)) {
1095 1111 if (SWAP_32(olvd->lvd_vdsn) <
1096 - SWAP_32(lvd->lvd_vdsn)) {
1112 + SWAP_32(lvd->lvd_vdsn)) {
1097 1113 udf_vfsp->udf_lvd = lvd;
1098 1114 }
1099 1115 } else {
1100 1116 goto out;
1101 1117 }
1102 1118 }
1103 1119 } else if (ud_verify_tag_and_desc(ttag, UD_PART_DESC,
1104 1120 vds_loc + (index >> shift),
1105 1121 1, desc_len) == 0) {
1106 1122 int32_t i;
1107 1123 struct phdr_desc *hdr;
1108 1124 struct part_desc *pdesc;
1109 1125 struct ud_part *pnew, *pold, *part;
1110 1126
1111 1127 pdesc = (struct part_desc *)ttag;
1112 1128 pold = udf_vfsp->udf_parts;
1113 1129 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;
1130 + if (pold->udp_number !=
1131 + SWAP_16(pdesc->pd_pnum)) {
1132 + pold++;
1133 + continue;
1128 1134 }
1129 - pold ++;
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;
1130 1148 }
1131 1149 pold = udf_vfsp->udf_parts;
1132 1150 udf_vfsp->udf_npart++;
1133 1151 pnew = kmem_zalloc(udf_vfsp->udf_npart *
1134 - sizeof (struct ud_part), KM_SLEEP);
1152 + sizeof (struct ud_part), KM_SLEEP);
1135 1153 udf_vfsp->udf_parts = pnew;
1136 1154 if (pold) {
1137 1155 bcopy(pold, pnew,
1138 - sizeof (struct ud_part) *
1139 - (udf_vfsp->udf_npart - 1));
1156 + sizeof (struct ud_part) *
1157 + (udf_vfsp->udf_npart - 1));
1140 1158 kmem_free(pold,
1141 - sizeof (struct ud_part) *
1142 - (udf_vfsp->udf_npart - 1));
1159 + sizeof (struct ud_part) *
1160 + (udf_vfsp->udf_npart - 1));
1143 1161 }
1144 1162 part = pnew + (udf_vfsp->udf_npart - 1);
1145 1163 part->udp_number = SWAP_16(pdesc->pd_pnum);
1146 1164 part->udp_seqno = SWAP_32(pdesc->pd_vdsn);
1147 1165 part->udp_access = SWAP_32(pdesc->pd_acc_type);
1148 1166 part->udp_start = SWAP_32(pdesc->pd_part_start);
1149 1167 part->udp_length = SWAP_32(pdesc->pd_part_length);
1150 1168 part->udp_last_alloc = 0;
1151 1169
1152 1170 /*
1153 1171 * Figure out space bitmaps
1154 1172 * or space tables
1155 1173 */
1156 1174 hdr = (struct phdr_desc *)pdesc->pd_pc_use;
1157 1175 if (hdr->phdr_ust.sad_ext_len) {
1158 1176 part->udp_flags = UDP_SPACETBLS;
1159 1177 part->udp_unall_loc =
1160 - SWAP_32(hdr->phdr_ust.sad_ext_loc);
1178 + SWAP_32(hdr->phdr_ust.sad_ext_loc);
1161 1179 part->udp_unall_len =
1162 - SWAP_32(hdr->phdr_ust.sad_ext_len);
1180 + SWAP_32(hdr->phdr_ust.sad_ext_len);
1163 1181 part->udp_freed_loc =
1164 - SWAP_32(hdr->phdr_fst.sad_ext_loc);
1182 + SWAP_32(hdr->phdr_fst.sad_ext_loc);
1165 1183 part->udp_freed_len =
1166 - SWAP_32(hdr->phdr_fst.sad_ext_len);
1184 + SWAP_32(hdr->phdr_fst.sad_ext_len);
1167 1185 } else {
1168 1186 part->udp_flags = UDP_BITMAPS;
1169 1187 part->udp_unall_loc =
1170 - SWAP_32(hdr->phdr_usb.sad_ext_loc);
1188 + SWAP_32(hdr->phdr_usb.sad_ext_loc);
1171 1189 part->udp_unall_len =
1172 - SWAP_32(hdr->phdr_usb.sad_ext_len);
1190 + SWAP_32(hdr->phdr_usb.sad_ext_len);
1173 1191 part->udp_freed_loc =
1174 - SWAP_32(hdr->phdr_fsb.sad_ext_loc);
1192 + SWAP_32(hdr->phdr_fsb.sad_ext_loc);
1175 1193 part->udp_freed_len =
1176 - SWAP_32(hdr->phdr_fsb.sad_ext_len);
1194 + SWAP_32(hdr->phdr_fsb.sad_ext_len);
1177 1195 }
1178 1196 } else if (ud_verify_tag_and_desc(ttag, UD_TERM_DESC,
1179 1197 vds_loc + (index >> shift),
1180 1198 1, desc_len) == 0) {
1181 1199
1182 1200 break;
1183 1201 }
1184 1202 loop_end:
1185 1203 ;
1186 1204 }
1187 1205 if ((udf_vfsp->udf_pvd == NULL) ||
1188 - (udf_vfsp->udf_lvd == NULL) ||
1189 - (udf_vfsp->udf_parts == NULL)) {
1206 + (udf_vfsp->udf_lvd == NULL) ||
1207 + (udf_vfsp->udf_parts == NULL)) {
1190 1208 goto out;
1191 1209 }
1192 1210
1193 1211 /*
1194 1212 * Process Primary Volume Descriptor
1195 1213 */
1196 1214 (void) strncpy(udf_vfsp->udf_volid, udf_vfsp->udf_pvd->pvd_vol_id, 32);
1197 1215 udf_vfsp->udf_volid[31] = '\0';
1198 1216 udf_vfsp->udf_tsno = SWAP_16(udf_vfsp->udf_pvd->pvd_tag.tag_sno);
1199 1217
1200 1218 /*
1201 1219 * Process Logical Volume Descriptor
1202 1220 */
1203 1221 udf_vfsp->udf_lbsize =
1204 - SWAP_32(udf_vfsp->udf_lvd->lvd_log_bsize);
1222 + SWAP_32(udf_vfsp->udf_lvd->lvd_log_bsize);
1205 1223 udf_vfsp->udf_lbmask = udf_vfsp->udf_lbsize - 1;
1206 1224 udf_vfsp->udf_l2d_shift = shift;
1207 1225 udf_vfsp->udf_l2b_shift = shift + DEV_BSHIFT;
1208 1226
1209 1227 /*
1210 1228 * Check if the media is in
1211 1229 * proper domain.
1212 1230 */
1213 1231 if (strcmp(udf_vfsp->udf_lvd->lvd_dom_id.reg_id,
1214 - UDF_DOMAIN_NAME) != 0) {
1232 + UDF_DOMAIN_NAME) != 0) {
1215 1233 goto out;
1216 1234 }
1217 1235
1218 1236 /*
1219 1237 * AVDS offset does not match with the lbsize
1220 1238 * in the lvd
1221 1239 */
1222 1240 if (udf_vfsp->udf_lbsize != bsize) {
1223 1241 goto out;
1224 1242 }
1225 1243
1226 1244 udf_vfsp->udf_iseq_loc =
1227 - SWAP_32(udf_vfsp->udf_lvd->lvd_int_seq_ext.ext_loc);
1245 + SWAP_32(udf_vfsp->udf_lvd->lvd_int_seq_ext.ext_loc);
1228 1246 udf_vfsp->udf_iseq_len =
1229 - SWAP_32(udf_vfsp->udf_lvd->lvd_int_seq_ext.ext_len);
1247 + SWAP_32(udf_vfsp->udf_lvd->lvd_int_seq_ext.ext_len);
1230 1248
1231 1249 udf_vfsp->udf_fsd_prn =
1232 - SWAP_16(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_prn);
1250 + SWAP_16(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_prn);
1233 1251 udf_vfsp->udf_fsd_loc =
1234 - SWAP_32(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_loc);
1252 + SWAP_32(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_loc);
1235 1253 udf_vfsp->udf_fsd_len =
1236 - SWAP_32(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_len);
1254 + SWAP_32(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_len);
1237 1255
1238 1256
1239 1257 /*
1240 1258 * process paritions
1241 1259 */
1242 1260 udf_vfsp->udf_mtype = udf_vfsp->udf_parts[0].udp_access;
1243 1261 for (index = 0; index < udf_vfsp->udf_npart; index ++) {
1244 1262 if (udf_vfsp->udf_parts[index].udp_access <
1245 - udf_vfsp->udf_mtype) {
1263 + udf_vfsp->udf_mtype) {
1246 1264 udf_vfsp->udf_mtype =
1247 - udf_vfsp->udf_parts[index].udp_access;
1265 + udf_vfsp->udf_parts[index].udp_access;
1248 1266 }
1249 1267 }
1250 1268 if ((udf_vfsp->udf_mtype < UDF_MT_RO) ||
1251 - (udf_vfsp->udf_mtype > UDF_MT_OW)) {
1269 + (udf_vfsp->udf_mtype > UDF_MT_OW)) {
1252 1270 udf_vfsp->udf_mtype = UDF_MT_RO;
1253 1271 }
1254 1272
1255 1273 udf_vfsp->udf_nmaps = 0;
1256 1274 hdr = (struct pmap_hdr *)udf_vfsp->udf_lvd->lvd_pmaps;
1257 1275 count = SWAP_32(udf_vfsp->udf_lvd->lvd_num_pmaps);
1258 1276 for (index = 0; index < count; index++) {
1259 1277
1260 1278 if ((hdr->maph_type == MAP_TYPE1) &&
1261 - (hdr->maph_length == MAP_TYPE1_LEN)) {
1279 + (hdr->maph_length == MAP_TYPE1_LEN)) {
1262 1280 typ1 = (struct pmap_typ1 *)hdr;
1263 1281
1264 1282 map = udf_vfsp->udf_maps;
1265 1283 udf_vfsp->udf_maps =
1266 - kmem_zalloc(sizeof (struct ud_map) *
1267 - (udf_vfsp->udf_nmaps + 1),
1268 - KM_SLEEP);
1284 + kmem_zalloc(sizeof (struct ud_map) *
1285 + (udf_vfsp->udf_nmaps + 1), KM_SLEEP);
1269 1286 if (map != NULL) {
1270 1287 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);
1288 + sizeof (struct ud_map) *
1289 + udf_vfsp->udf_nmaps);
1290 + kmem_free(map, sizeof (struct ud_map) *
1291 + udf_vfsp->udf_nmaps);
1274 1292 }
1275 1293 map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps;
1276 1294 map->udm_flags = UDM_MAP_NORM;
1277 1295 map->udm_vsn = SWAP_16(typ1->map1_vsn);
1278 1296 map->udm_pn = SWAP_16(typ1->map1_pn);
1279 1297 udf_vfsp->udf_nmaps ++;
1280 1298 } else if ((hdr->maph_type == MAP_TYPE2) &&
1281 - (hdr->maph_length == MAP_TYPE2_LEN)) {
1299 + (hdr->maph_length == MAP_TYPE2_LEN)) {
1282 1300 typ2 = (struct pmap_typ2 *)hdr;
1283 1301
1284 1302 if (strncmp(typ2->map2_pti.reg_id,
1285 - UDF_VIRT_PART, 23) == 0) {
1303 + UDF_VIRT_PART, 23) == 0) {
1286 1304 /*
1287 1305 * Add this to the normal
1288 1306 * partition table so that
1289 1307 * we donot
1290 1308 */
1291 1309 map = udf_vfsp->udf_maps;
1292 1310 udf_vfsp->udf_maps =
1293 - kmem_zalloc(sizeof (struct ud_map) *
1294 - (udf_vfsp->udf_nmaps + 1),
1295 - KM_SLEEP);
1311 + kmem_zalloc(sizeof (struct ud_map) *
1312 + (udf_vfsp->udf_nmaps + 1), KM_SLEEP);
1296 1313 if (map != NULL) {
1297 1314 bcopy(map, udf_vfsp->udf_maps,
1298 - sizeof (struct ud_map) *
1299 - udf_vfsp->udf_nmaps);
1315 + sizeof (struct ud_map) *
1316 + udf_vfsp->udf_nmaps);
1300 1317 kmem_free(map,
1301 - sizeof (struct ud_map) *
1302 - udf_vfsp->udf_nmaps);
1318 + sizeof (struct ud_map) *
1319 + udf_vfsp->udf_nmaps);
1303 1320 }
1304 1321 map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps;
1305 1322 map->udm_flags = UDM_MAP_VPM;
1306 1323 map->udm_vsn = SWAP_16(typ2->map2_vsn);
1307 1324 map->udm_pn = SWAP_16(typ2->map2_pn);
1308 1325 udf_vfsp->udf_nmaps ++;
1309 1326 if (error = ud_get_last_block(dev, &lblkno)) {
1310 1327 goto out;
1311 1328 }
1312 1329 if (error = ud_val_get_vat(udf_vfsp, dev,
1313 - lblkno, map)) {
1330 + lblkno, map)) {
1314 1331 goto out;
1315 1332 }
1316 1333 } else if (strncmp(typ2->map2_pti.reg_id,
1317 - UDF_SPAR_PART, 23) == 0) {
1334 + UDF_SPAR_PART, 23) == 0) {
1318 1335
1319 1336 if (SWAP_16(typ2->map2_pl) != 32) {
1320 1337 printf(
1321 - "Packet Length is not valid %x\n",
1322 - SWAP_16(typ2->map2_pl));
1338 + "Packet Length is not valid %x\n",
1339 + SWAP_16(typ2->map2_pl));
1323 1340 goto out;
1324 1341 }
1325 1342 if ((typ2->map2_nst < 1) ||
1326 - (typ2->map2_nst > 4)) {
1343 + (typ2->map2_nst > 4)) {
1327 1344 goto out;
1328 1345 }
1329 1346 map = udf_vfsp->udf_maps;
1330 1347 udf_vfsp->udf_maps =
1331 - kmem_zalloc(sizeof (struct ud_map) *
1332 - (udf_vfsp->udf_nmaps + 1),
1333 - KM_SLEEP);
1348 + kmem_zalloc(sizeof (struct ud_map) *
1349 + (udf_vfsp->udf_nmaps + 1),
1350 + KM_SLEEP);
1334 1351 if (map != NULL) {
1335 1352 bcopy(map, udf_vfsp->udf_maps,
1336 - sizeof (struct ud_map) *
1337 - udf_vfsp->udf_nmaps);
1353 + sizeof (struct ud_map) *
1354 + udf_vfsp->udf_nmaps);
1338 1355 kmem_free(map,
1339 - sizeof (struct ud_map) *
1340 - udf_vfsp->udf_nmaps);
1356 + sizeof (struct ud_map) *
1357 + udf_vfsp->udf_nmaps);
1341 1358 }
1342 1359 map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps;
1343 1360 map->udm_flags = UDM_MAP_SPM;
1344 1361 map->udm_vsn = SWAP_16(typ2->map2_vsn);
1345 1362 map->udm_pn = SWAP_16(typ2->map2_pn);
1346 1363
1347 1364 udf_vfsp->udf_nmaps ++;
1348 1365
1349 1366 if (error = ud_read_sparing_tbls(udf_vfsp,
1350 - dev, map, typ2)) {
1367 + dev, map, typ2)) {
1351 1368 goto out;
1352 1369 }
1353 1370 } else {
1354 1371 /*
1355 1372 * Unknown type of partition
1356 1373 * Bail out
1357 1374 */
1358 1375 goto out;
1359 1376 }
1360 1377 } else {
1361 1378 /*
1362 1379 * Unknown type of partition
1363 1380 * Bail out
1364 1381 */
1365 1382 goto out;
|
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
1366 1383 }
1367 1384 hdr = (struct pmap_hdr *)(((uint8_t *)hdr) + hdr->maph_length);
1368 1385 }
1369 1386
1370 1387
1371 1388 /*
1372 1389 * Read Logical Volume Integrity Sequence
1373 1390 * and process it
1374 1391 */
1375 1392 secbp = ud_bread(dev, udf_vfsp->udf_iseq_loc << shift,
1376 - udf_vfsp->udf_iseq_len);
1393 + udf_vfsp->udf_iseq_len);
1377 1394 if ((error = geterror(secbp)) != 0) {
1378 1395 cmn_err(CE_NOTE,
1379 1396 "udfs : Could not read Logical Volume Integrity Sequence %x",
1380 - error);
1397 + error);
1381 1398 brelse(secbp);
1382 1399 goto out;
1383 1400 }
1384 1401 udf_vfsp->udf_iseq = ngeteblk(udf_vfsp->udf_iseq_len);
1385 1402 bp = udf_vfsp->udf_iseq;
1386 1403 bp->b_edev = dev;
1387 1404 bp->b_dev = cmpdev(dev);
1388 1405 bp->b_blkno = udf_vfsp->udf_iseq_loc << shift;
1389 1406 bp->b_bcount = udf_vfsp->udf_iseq_len;
1390 1407 bcopy(secbp->b_un.b_addr, bp->b_un.b_addr, udf_vfsp->udf_iseq_len);
1391 1408 secbp->b_flags |= B_STALE | B_AGE;
1392 1409 brelse(secbp);
1393 1410
1394 1411 count = udf_vfsp->udf_iseq_len / DEV_BSIZE;
1395 1412 addr = bp->b_un.b_addr;
1396 1413 for (index = 0; index < count; index ++) {
1397 1414 ttag = (struct tag *)(addr + index * DEV_BSIZE);
1398 1415 desc_len = udf_vfsp->udf_iseq_len - (index * DEV_BSIZE);
1399 1416 if (ud_verify_tag_and_desc(ttag, UD_LOG_VOL_INT,
1400 1417 udf_vfsp->udf_iseq_loc + (index >> shift),
1401 1418 1, desc_len) == 0) {
1402 1419
1403 1420 struct log_vol_int_desc *lvid;
1404 1421
1405 1422 lvid = (struct log_vol_int_desc *)ttag;
1406 1423 udf_vfsp->udf_lvid = lvid;
1407 1424
1408 1425 if (SWAP_32(lvid->lvid_int_type) == LOG_VOL_CLOSE_INT) {
1409 1426 udf_vfsp->udf_clean = UDF_CLEAN;
1410 1427 } else {
1411 1428 udf_vfsp->udf_clean = UDF_DIRTY;
1412 1429 }
1413 1430
1414 1431 /*
1415 1432 * update superblock with the metadata
1416 1433 */
|
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
1417 1434 ud_convert_to_superblock(udf_vfsp, lvid);
1418 1435 break;
1419 1436 }
1420 1437 }
1421 1438
1422 1439 if (udf_vfsp->udf_lvid == NULL) {
1423 1440 goto out;
1424 1441 }
1425 1442
1426 1443 if ((blkno = ud_xlate_to_daddr(udf_vfsp,
1427 - udf_vfsp->udf_fsd_prn, udf_vfsp->udf_fsd_loc,
1428 - 1, &dummy)) == 0) {
1444 + udf_vfsp->udf_fsd_prn, udf_vfsp->udf_fsd_loc,
1445 + 1, &dummy)) == 0) {
1429 1446 goto out;
1430 1447 }
1431 1448 secbp = ud_bread(dev, blkno << shift, udf_vfsp->udf_fsd_len);
1432 1449 if ((error = geterror(secbp)) != 0) {
1433 1450 cmn_err(CE_NOTE,
1434 1451 "udfs : Could not read File Set Descriptor %x", error);
1435 1452 brelse(secbp);
1436 1453 goto out;
1437 1454 }
1438 1455 fsd = (struct file_set_desc *)secbp->b_un.b_addr;
1439 1456 if (ud_verify_tag_and_desc(&fsd->fsd_tag, UD_FILE_SET_DESC,
1440 1457 udf_vfsp->udf_fsd_loc,
1441 1458 1, udf_vfsp->udf_fsd_len) != 0) {
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
1442 1459 secbp->b_flags = B_AGE | B_STALE;
1443 1460 brelse(secbp);
1444 1461 goto out;
1445 1462 }
1446 1463 udf_vfsp->udf_ricb_prn = SWAP_16(fsd->fsd_root_icb.lad_ext_prn);
1447 1464 udf_vfsp->udf_ricb_loc = SWAP_32(fsd->fsd_root_icb.lad_ext_loc);
1448 1465 udf_vfsp->udf_ricb_len = SWAP_32(fsd->fsd_root_icb.lad_ext_len);
1449 1466 secbp->b_flags = B_AGE | B_STALE;
1450 1467 brelse(secbp);
1451 1468 udf_vfsp->udf_root_blkno = ud_xlate_to_daddr(udf_vfsp,
1452 - udf_vfsp->udf_ricb_prn, udf_vfsp->udf_ricb_loc,
1453 - 1, &dummy);
1469 + udf_vfsp->udf_ricb_prn, udf_vfsp->udf_ricb_loc,
1470 + 1, &dummy);
1454 1471
1455 1472 return (udf_vfsp);
1456 1473 out:
1457 1474 ud_destroy_fsp(udf_vfsp);
1458 1475
1459 1476 return (NULL);
1460 1477 }
1461 1478
1462 1479 /*
1463 1480 * release/free resources from one ud_map; map data was zalloc'd in
1464 1481 * ud_validate_and_fill_superblock() and fields may later point to
1465 1482 * valid data
1466 1483 */
1467 1484 static void
1468 1485 ud_free_map(struct ud_map *map)
1469 1486 {
1470 1487 uint32_t n;
1471 1488
1472 1489 if (map->udm_flags & UDM_MAP_VPM) {
1473 1490 if (map->udm_count) {
1474 1491 kmem_free(map->udm_count,
1475 1492 map->udm_nent * sizeof (*map->udm_count));
1476 1493 map->udm_count = NULL;
1477 1494 }
1478 1495 if (map->udm_bp) {
1479 1496 for (n = 0; n < map->udm_nent; n++) {
1480 1497 if (map->udm_bp[n])
1481 1498 brelse(map->udm_bp[n]);
1482 1499 }
1483 1500 kmem_free(map->udm_bp,
1484 1501 map->udm_nent * sizeof (*map->udm_bp));
1485 1502 map->udm_bp = NULL;
1486 1503 }
1487 1504 if (map->udm_addr) {
1488 1505 kmem_free(map->udm_addr,
1489 1506 map->udm_nent * sizeof (*map->udm_addr));
1490 1507 map->udm_addr = NULL;
1491 1508 }
1492 1509 }
1493 1510 if (map->udm_flags & UDM_MAP_SPM) {
1494 1511 for (n = 0; n < MAX_SPM; n++) {
1495 1512 if (map->udm_sbp[n]) {
1496 1513 brelse(map->udm_sbp[n]);
1497 1514 map->udm_sbp[n] = NULL;
1498 1515 map->udm_spaddr[n] = NULL;
1499 1516 }
1500 1517 }
1501 1518 }
1502 1519 }
1503 1520
1504 1521 void
1505 1522 ud_destroy_fsp(struct udf_vfs *udf_vfsp)
1506 1523 {
1507 1524 int32_t i;
1508 1525
1509 1526 ud_printf("ud_destroy_fsp\n");
1510 1527 if (udf_vfsp == NULL)
1511 1528 return;
1512 1529
1513 1530 if (udf_vfsp->udf_maps) {
1514 1531 for (i = 0; i < udf_vfsp->udf_nmaps; i++)
1515 1532 ud_free_map(&udf_vfsp->udf_maps[i]);
1516 1533
1517 1534 kmem_free(udf_vfsp->udf_maps,
1518 1535 udf_vfsp->udf_nmaps * sizeof (*udf_vfsp->udf_maps));
1519 1536 }
1520 1537
1521 1538 if (udf_vfsp->udf_parts) {
1522 1539 kmem_free(udf_vfsp->udf_parts,
1523 1540 udf_vfsp->udf_npart * sizeof (*udf_vfsp->udf_parts));
1524 1541 }
1525 1542 if (udf_vfsp->udf_iseq) {
1526 1543 udf_vfsp->udf_iseq->b_flags |= (B_STALE|B_AGE);
1527 1544 brelse(udf_vfsp->udf_iseq);
1528 1545 }
1529 1546 if (udf_vfsp->udf_vds) {
1530 1547 udf_vfsp->udf_vds->b_flags |= (B_STALE|B_AGE);
1531 1548 brelse(udf_vfsp->udf_vds);
1532 1549 }
1533 1550 if (udf_vfsp->udf_vfs)
1534 1551 ud_vfs_remove(udf_vfsp);
1535 1552 if (udf_vfsp->udf_fsmnt) {
1536 1553 kmem_free(udf_vfsp->udf_fsmnt,
1537 1554 strlen(udf_vfsp->udf_fsmnt) + 1);
1538 1555 }
1539 1556 kmem_free(udf_vfsp, sizeof (*udf_vfsp));
1540 1557 }
1541 1558
1542 1559 void
1543 1560 ud_convert_to_superblock(struct udf_vfs *udf_vfsp,
1544 1561 struct log_vol_int_desc *lvid)
1545 1562 {
1546 1563 int32_t i, c;
1547 1564 uint32_t *temp;
1548 1565 struct ud_part *ud_part;
1549 1566 struct lvid_iu *iu;
1550 1567
1551 1568 udf_vfsp->udf_maxuniq = SWAP_64(lvid->lvid_uniqid);
1552 1569 temp = lvid->lvid_fst;
1553 1570 c = SWAP_32(lvid->lvid_npart);
1554 1571 ud_part = udf_vfsp->udf_parts;
1555 1572 for (i = 0; i < c; i++) {
1556 1573 if (i >= udf_vfsp->udf_npart) {
1557 1574 continue;
1558 1575 }
1559 1576 ud_part->udp_nfree = SWAP_32(temp[i]);
1560 1577 ud_part->udp_nblocks = SWAP_32(temp[c + i]);
1561 1578 udf_vfsp->udf_freeblks += SWAP_32(temp[i]);
1562 1579 udf_vfsp->udf_totalblks += SWAP_32(temp[c + i]);
1563 1580 ud_part++;
1564 1581 }
1565 1582
1566 1583 iu = (struct lvid_iu *)(temp + c * 2);
1567 1584 udf_vfsp->udf_nfiles = SWAP_32(iu->lvidiu_nfiles);
1568 1585 udf_vfsp->udf_ndirs = SWAP_32(iu->lvidiu_ndirs);
1569 1586 udf_vfsp->udf_miread = BCD2HEX_16(SWAP_16(iu->lvidiu_mread));
1570 1587 udf_vfsp->udf_miwrite = BCD2HEX_16(SWAP_16(iu->lvidiu_mwrite));
1571 1588 udf_vfsp->udf_mawrite = BCD2HEX_16(SWAP_16(iu->lvidiu_maxwr));
1572 1589 }
1573 1590
1574 1591 void
1575 1592 ud_update_superblock(struct vfs *vfsp)
1576 1593 {
1577 1594 struct udf_vfs *udf_vfsp;
1578 1595
1579 1596 ud_printf("ud_update_superblock\n");
1580 1597
1581 1598 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data;
1582 1599
1583 1600 mutex_enter(&udf_vfsp->udf_lock);
1584 1601 ud_sbwrite(udf_vfsp);
1585 1602 mutex_exit(&udf_vfsp->udf_lock);
1586 1603 }
1587 1604
1588 1605
1589 1606 #include <sys/dkio.h>
1590 1607 #include <sys/cdio.h>
1591 1608 #include <sys/vtoc.h>
1592 1609
1593 1610 /*
1594 1611 * This part of the code is known
1595 1612 * to work with only sparc. It needs
|
↓ open down ↓ |
132 lines elided |
↑ open up ↑ |
1596 1613 * to be evluated before using it with x86
1597 1614 */
1598 1615 int32_t
1599 1616 ud_get_last_block(dev_t dev, daddr_t *blkno)
1600 1617 {
1601 1618 struct vtoc vtoc;
1602 1619 struct dk_cinfo dki_info;
1603 1620 int32_t rval, error;
1604 1621
1605 1622 if ((error = cdev_ioctl(dev, DKIOCGVTOC, (intptr_t)&vtoc,
1606 - FKIOCTL|FREAD|FNATIVE, CRED(), &rval)) != 0) {
1623 + FKIOCTL|FREAD|FNATIVE, CRED(), &rval)) != 0) {
1607 1624 cmn_err(CE_NOTE, "Could not get the vtoc information");
1608 1625 return (error);
1609 1626 }
1610 1627
1611 1628 if (vtoc.v_sanity != VTOC_SANE) {
1612 1629 return (EINVAL);
1613 1630 }
1614 1631 if ((error = cdev_ioctl(dev, DKIOCINFO, (intptr_t)&dki_info,
1615 - FKIOCTL|FREAD|FNATIVE, CRED(), &rval)) != 0) {
1632 + FKIOCTL|FREAD|FNATIVE, CRED(), &rval)) != 0) {
1616 1633 cmn_err(CE_NOTE, "Could not get the slice information");
1617 1634 return (error);
1618 1635 }
1619 1636
1620 1637 if (dki_info.dki_partition > V_NUMPAR) {
1621 1638 return (EINVAL);
1622 1639 }
1623 1640
1624 1641
1625 1642 *blkno = vtoc.v_part[dki_info.dki_partition].p_size;
1626 1643
1627 1644 return (0);
1628 1645 }
1629 1646
1630 1647 /* Search sequentially N - 2, N, N - 152, N - 150 for vat icb */
1631 1648 /*
1632 1649 * int32_t ud_sub_blks[] = {2, 0, 152, 150};
1633 1650 */
1634 1651 int32_t ud_sub_blks[] = {152, 150, 2, 0};
1635 1652 int32_t ud_sub_count = 4;
1636 1653
1637 1654 /*
1638 1655 * Validate the VAT ICB
1639 1656 */
1640 1657 static int32_t
1641 1658 ud_val_get_vat(struct udf_vfs *udf_vfsp, dev_t dev,
1642 1659 daddr_t blkno, struct ud_map *udm)
1643 1660 {
1644 1661 struct buf *secbp;
1645 1662 struct file_entry *fe;
1646 1663 int32_t end_loc, i, j, ad_type;
1647 1664 struct short_ad *sad;
1648 1665 struct long_ad *lad;
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
1649 1666 uint32_t count, blk;
1650 1667 struct ud_part *ud_part;
1651 1668 int err = 0;
1652 1669
1653 1670 end_loc = (blkno >> udf_vfsp->udf_l2d_shift) - 1;
1654 1671
1655 1672 for (i = 0; i < ud_sub_count; i++) {
1656 1673 udm->udm_vat_icb = end_loc - ud_sub_blks[i];
1657 1674
1658 1675 secbp = ud_bread(dev,
1659 - udm->udm_vat_icb << udf_vfsp->udf_l2d_shift,
1660 - udf_vfsp->udf_lbsize);
1676 + udm->udm_vat_icb << udf_vfsp->udf_l2d_shift,
1677 + udf_vfsp->udf_lbsize);
1661 1678 ASSERT(secbp->b_un.b_addr);
1662 1679
1663 1680 fe = (struct file_entry *)secbp->b_un.b_addr;
1664 1681 if (ud_verify_tag_and_desc(&fe->fe_tag, UD_FILE_ENTRY, 0,
1665 1682 0, 0) == 0) {
1666 1683 if (ud_verify_tag_and_desc(&fe->fe_tag, UD_FILE_ENTRY,
1667 1684 SWAP_32(fe->fe_tag.tag_loc),
1668 1685 1, udf_vfsp->udf_lbsize) == 0) {
1669 1686 if (fe->fe_icb_tag.itag_ftype == 0) {
1670 1687 break;
1671 1688 }
1672 1689 }
1673 1690 }
1674 1691 secbp->b_flags |= B_AGE | B_STALE;
1675 1692 brelse(secbp);
|
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
1676 1693 }
1677 1694 if (i == ud_sub_count) {
1678 1695 return (EINVAL);
1679 1696 }
1680 1697
1681 1698 ad_type = SWAP_16(fe->fe_icb_tag.itag_flags) & 0x3;
1682 1699 if (ad_type == ICB_FLAG_ONE_AD) {
1683 1700 udm->udm_nent = 1;
1684 1701 } else if (ad_type == ICB_FLAG_SHORT_AD) {
1685 1702 udm->udm_nent =
1686 - SWAP_32(fe->fe_len_adesc) / sizeof (struct short_ad);
1703 + SWAP_32(fe->fe_len_adesc) / sizeof (struct short_ad);
1687 1704 } else if (ad_type == ICB_FLAG_LONG_AD) {
1688 1705 udm->udm_nent =
1689 - SWAP_32(fe->fe_len_adesc) / sizeof (struct long_ad);
1706 + SWAP_32(fe->fe_len_adesc) / sizeof (struct long_ad);
1690 1707 } else {
1691 1708 err = EINVAL;
1692 1709 goto end;
1693 1710 }
1694 1711
1695 1712 udm->udm_count = kmem_zalloc(udm->udm_nent * sizeof (*udm->udm_count),
1696 1713 KM_SLEEP);
1697 1714 udm->udm_bp = kmem_zalloc(udm->udm_nent * sizeof (*udm->udm_bp),
1698 1715 KM_SLEEP);
1699 1716 udm->udm_addr = kmem_zalloc(udm->udm_nent * sizeof (*udm->udm_addr),
1700 1717 KM_SLEEP);
1701 1718
1702 1719 if (ad_type == ICB_FLAG_ONE_AD) {
1703 1720 udm->udm_count[0] = (SWAP_64(fe->fe_info_len) - 36) /
1704 - sizeof (uint32_t);
1721 + sizeof (uint32_t);
1705 1722 udm->udm_bp[0] = secbp;
1706 1723 udm->udm_addr[0] = (uint32_t *)
1707 - &fe->fe_spec[SWAP_32(fe->fe_len_ear)];
1724 + &fe->fe_spec[SWAP_32(fe->fe_len_ear)];
1708 1725 return (0);
1709 1726 }
1710 1727 for (i = 0; i < udm->udm_nent; i++) {
1711 1728 if (ad_type == ICB_FLAG_SHORT_AD) {
1712 1729 sad = (struct short_ad *)
1713 - (fe->fe_spec + SWAP_32(fe->fe_len_ear));
1730 + (fe->fe_spec + SWAP_32(fe->fe_len_ear));
1714 1731 sad += i;
1715 1732 count = SWAP_32(sad->sad_ext_len);
1716 1733 blk = SWAP_32(sad->sad_ext_loc);
1717 1734 } else {
1718 1735 lad = (struct long_ad *)
1719 - (fe->fe_spec + SWAP_32(fe->fe_len_ear));
1736 + (fe->fe_spec + SWAP_32(fe->fe_len_ear));
1720 1737 lad += i;
1721 1738 count = SWAP_32(lad->lad_ext_len);
1722 1739 blk = SWAP_32(lad->lad_ext_loc);
1723 1740 ASSERT(SWAP_16(lad->lad_ext_prn) == udm->udm_pn);
1724 1741 }
1725 1742 if ((count & 0x3FFFFFFF) == 0) {
1726 1743 break;
1727 1744 }
1728 1745 if (i < udm->udm_nent - 1) {
1729 1746 udm->udm_count[i] = count / 4;
1730 1747 } else {
1731 1748 udm->udm_count[i] = (count - 36) / 4;
1732 1749 }
1733 1750 ud_part = udf_vfsp->udf_parts;
1734 1751 for (j = 0; j < udf_vfsp->udf_npart; j++) {
1735 1752 if (udm->udm_pn == ud_part->udp_number) {
1736 1753 blk = ud_part->udp_start + blk;
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
1737 1754 break;
1738 1755 }
1739 1756 }
1740 1757 if (j == udf_vfsp->udf_npart) {
1741 1758 err = EINVAL;
1742 1759 break;
1743 1760 }
1744 1761
1745 1762 count = (count + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
1746 1763 udm->udm_bp[i] = ud_bread(dev,
1747 - blk << udf_vfsp->udf_l2d_shift, count);
1764 + blk << udf_vfsp->udf_l2d_shift, count);
1748 1765 if ((udm->udm_bp[i]->b_error != 0) ||
1749 - (udm->udm_bp[i]->b_resid)) {
1766 + (udm->udm_bp[i]->b_resid)) {
1750 1767 err = EINVAL;
1751 1768 break;
1752 1769 }
1753 1770 udm->udm_addr[i] = (uint32_t *)udm->udm_bp[i]->b_un.b_addr;
1754 1771 }
1755 1772
1756 1773 end:
1757 1774 if (err)
1758 1775 ud_free_map(udm);
1759 1776 secbp->b_flags |= B_AGE | B_STALE;
1760 1777 brelse(secbp);
1761 1778 return (err);
1762 1779 }
1763 1780
1764 1781 int32_t
1765 1782 ud_read_sparing_tbls(struct udf_vfs *udf_vfsp,
1766 1783 dev_t dev, struct ud_map *map, struct pmap_typ2 *typ2)
1767 1784 {
1768 1785 int32_t index, valid = 0;
1769 1786 uint32_t sz;
1770 1787 struct buf *bp;
1771 1788 struct stbl *stbl;
1772 1789
1773 1790 map->udm_plen = SWAP_16(typ2->map2_pl);
1774 1791 map->udm_nspm = typ2->map2_nst;
|
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
1775 1792 map->udm_spsz = SWAP_32(typ2->map2_sest);
1776 1793 sz = (map->udm_spsz + udf_vfsp->udf_lbmask) & ~udf_vfsp->udf_lbmask;
1777 1794 if (sz == 0) {
1778 1795 return (0);
1779 1796 }
1780 1797
1781 1798 for (index = 0; index < map->udm_nspm; index++) {
1782 1799 map->udm_loc[index] = SWAP_32(typ2->map2_st[index]);
1783 1800
1784 1801 bp = ud_bread(dev,
1785 - map->udm_loc[index] << udf_vfsp->udf_l2d_shift, sz);
1802 + map->udm_loc[index] << udf_vfsp->udf_l2d_shift, sz);
1786 1803 if ((bp->b_error != 0) || (bp->b_resid)) {
1787 1804 brelse(bp);
1788 1805 continue;
1789 1806 }
1790 1807 stbl = (struct stbl *)bp->b_un.b_addr;
1791 1808 if (strncmp(stbl->stbl_si.reg_id, UDF_SPAR_TBL, 23) != 0) {
1792 1809 printf("Sparing Identifier does not match\n");
1793 1810 bp->b_flags |= B_AGE | B_STALE;
1794 1811 brelse(bp);
1795 1812 continue;
1796 1813 }
1797 1814 map->udm_sbp[index] = bp;
1798 1815 map->udm_spaddr[index] = bp->b_un.b_addr;
1799 1816 #ifdef UNDEF
1800 1817 {
1801 1818 struct stbl_entry *te;
1802 1819 int32_t i, tbl_len;
1803 1820
1804 1821 te = (struct stbl_entry *)&stbl->stbl_entry;
1805 1822 tbl_len = SWAP_16(stbl->stbl_len);
1806 1823
1807 1824 printf("%x %x\n", tbl_len, SWAP_32(stbl->stbl_seqno));
1808 1825 printf("%x %x\n", bp->b_un.b_addr, te);
1809 1826
1810 1827 for (i = 0; i < tbl_len; i++) {
1811 1828 printf("%x %x\n", SWAP_32(te->sent_ol), SWAP_32(te->sent_ml));
1812 1829 te ++;
1813 1830 }
1814 1831 }
1815 1832 #endif
1816 1833 valid ++;
1817 1834 }
1818 1835
1819 1836 if (valid) {
1820 1837 return (0);
1821 1838 }
1822 1839 return (EINVAL);
1823 1840 }
1824 1841
1825 1842 uint32_t
1826 1843 ud_get_lbsize(dev_t dev, uint32_t *loc)
1827 1844 {
1828 1845 int32_t bsize, shift, index, end_index;
1829 1846 daddr_t last_block;
1830 1847 uint32_t avd_loc;
1831 1848 struct buf *bp;
1832 1849 struct anch_vol_desc_ptr *avdp;
|
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
1833 1850 uint32_t session_offset = 0;
1834 1851 int32_t rval;
1835 1852
1836 1853 if (ud_get_last_block(dev, &last_block) != 0) {
1837 1854 end_index = 1;
1838 1855 } else {
1839 1856 end_index = 3;
1840 1857 }
1841 1858
1842 1859 if (cdev_ioctl(dev, CDROMREADOFFSET, (intptr_t)&session_offset,
1843 - FKIOCTL|FREAD|FNATIVE, CRED(), &rval) != 0) {
1860 + FKIOCTL|FREAD|FNATIVE, CRED(), &rval) != 0) {
1844 1861 session_offset = 0;
1845 1862 }
1846 1863
1847 1864 for (index = 0; index < end_index; index++) {
1848 1865
1849 1866 for (bsize = DEV_BSIZE, shift = 0;
1850 - bsize <= MAXBSIZE; bsize <<= 1, shift++) {
1867 + bsize <= MAXBSIZE; bsize <<= 1, shift++) {
1851 1868
1852 1869 if (index == 0) {
1853 1870 avd_loc = 256;
1854 1871 if (bsize <= 2048) {
1855 1872 avd_loc +=
1856 - session_offset * 2048 / bsize;
1873 + session_offset * 2048 / bsize;
1857 1874 } else {
1858 1875 avd_loc +=
1859 - session_offset / (bsize / 2048);
1876 + session_offset / (bsize / 2048);
1860 1877 }
1861 1878 } else if (index == 1) {
1862 1879 avd_loc = last_block - (1 << shift);
1863 1880 } else {
1864 1881 avd_loc = last_block - (256 << shift);
1865 1882 }
1866 1883
1867 1884 bp = ud_bread(dev, avd_loc << shift,
1868 - ANCHOR_VOL_DESC_LEN);
1885 + ANCHOR_VOL_DESC_LEN);
1869 1886 if (geterror(bp) != 0) {
1870 1887 brelse(bp);
1871 1888 continue;
1872 1889 }
1873 1890
1874 1891 /*
1875 1892 * Verify if we have avdp here
1876 1893 */
1877 1894 avdp = (struct anch_vol_desc_ptr *)bp->b_un.b_addr;
1878 1895 if (ud_verify_tag_and_desc(&avdp->avd_tag,
1879 1896 UD_ANCH_VOL_DESC, avd_loc,
1880 1897 1, ANCHOR_VOL_DESC_LEN) != 0) {
1881 1898 bp->b_flags |= B_AGE | B_STALE;
1882 1899 brelse(bp);
1883 1900 continue;
1884 1901 }
1885 1902 bp->b_flags |= B_AGE | B_STALE;
1886 1903 brelse(bp);
1887 1904 *loc = avd_loc;
1888 1905 return (bsize);
1889 1906 }
1890 1907 }
1891 1908
1892 1909 /*
1893 1910 * Did not find AVD at all the locations
1894 1911 */
1895 1912 return (0);
1896 1913 }
1897 1914
1898 1915 static int
1899 1916 udfinit(int fstype, char *name)
1900 1917 {
1901 1918 static const fs_operation_def_t udf_vfsops_template[] = {
1902 1919 VFSNAME_MOUNT, { .vfs_mount = udf_mount },
1903 1920 VFSNAME_UNMOUNT, { .vfs_unmount = udf_unmount },
1904 1921 VFSNAME_ROOT, { .vfs_root = udf_root },
1905 1922 VFSNAME_STATVFS, { .vfs_statvfs = udf_statvfs },
1906 1923 VFSNAME_SYNC, { .vfs_sync = udf_sync },
1907 1924 VFSNAME_VGET, { .vfs_vget = udf_vget },
1908 1925 VFSNAME_MOUNTROOT, { .vfs_mountroot = udf_mountroot },
1909 1926 NULL, NULL
1910 1927 };
1911 1928 extern struct vnodeops *udf_vnodeops;
1912 1929 extern const fs_operation_def_t udf_vnodeops_template[];
1913 1930 int error;
1914 1931
1915 1932 ud_printf("udfinit\n");
1916 1933
1917 1934 error = vfs_setfsops(fstype, udf_vfsops_template, NULL);
1918 1935 if (error != 0) {
1919 1936 cmn_err(CE_WARN, "udfinit: bad vfs ops template");
1920 1937 return (error);
1921 1938 }
1922 1939
1923 1940 error = vn_make_ops(name, udf_vnodeops_template, &udf_vnodeops);
1924 1941 if (error != 0) {
1925 1942 (void) vfs_freevfsops_by_type(fstype);
1926 1943 cmn_err(CE_WARN, "udfinit: bad vnode ops template");
1927 1944 return (error);
1928 1945 }
1929 1946
1930 1947 udf_fstype = fstype;
1931 1948
1932 1949 ud_init_inodes();
1933 1950
1934 1951 return (0);
1935 1952 }
|
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX