3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley
6 * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
7 * Support code is derived from software contributed to Berkeley
8 * by Atsushi Murai (amurai@spec.co.jp).
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * @(#)cd9660_vfsops.c 8.18 (Berkeley) 5/22/95
39 * $FreeBSD: src/sys/isofs/cd9660/cd9660_vfsops.c,v 1.74.2.7 2002/04/08 09:39:29 bde Exp $
40 * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vfsops.c,v 1.46 2008/09/17 21:44:23 dillon Exp $
43 #include <sys/param.h>
44 #include <sys/systm.h>
47 #include <sys/nlookup.h>
48 #include <sys/kernel.h>
49 #include <sys/vnode.h>
50 #include <sys/mount.h>
54 #include <sys/fcntl.h>
55 #include <sys/malloc.h>
57 #include <sys/syslog.h>
59 #include <vm/vm_zone.h>
63 #include "cd9660_node.h"
64 #include "cd9660_mount.h"
66 extern struct vop_ops cd9660_vnode_vops
;
67 extern struct vop_ops cd9660_spec_vops
;
68 extern struct vop_ops cd9660_fifo_vops
;
70 MALLOC_DEFINE(M_ISOFSMNT
, "ISOFS mount", "ISOFS mount structure");
71 MALLOC_DEFINE(M_ISOFSNODE
, "ISOFS node", "ISOFS vnode private part");
73 static int cd9660_mount (struct mount
*, char *, caddr_t
, struct ucred
*);
74 static int cd9660_unmount (struct mount
*, int);
75 static int cd9660_root (struct mount
*, struct vnode
**);
76 static int cd9660_statfs (struct mount
*, struct statfs
*, struct ucred
*);
77 static int cd9660_vget (struct mount
*, struct vnode
*, ino_t
, struct vnode
**);
78 static int cd9660_fhtovp (struct mount
*, struct vnode
*rootvp
,
79 struct fid
*, struct vnode
**);
80 static int cd9660_checkexp (struct mount
*, struct sockaddr
*,
81 int *, struct ucred
**);
82 static int cd9660_vptofh (struct vnode
*, struct fid
*);
84 static struct vfsops cd9660_vfsops
= {
85 .vfs_mount
= cd9660_mount
,
86 .vfs_unmount
= cd9660_unmount
,
87 .vfs_root
= cd9660_root
,
88 .vfs_statfs
= cd9660_statfs
,
89 .vfs_sync
= vfs_stdsync
,
90 .vfs_vget
= cd9660_vget
,
91 .vfs_fhtovp
= cd9660_fhtovp
,
92 .vfs_checkexp
= cd9660_checkexp
,
93 .vfs_vptofh
= cd9660_vptofh
,
94 .vfs_init
= cd9660_init
,
95 .vfs_uninit
= cd9660_uninit
,
97 VFS_SET(cd9660_vfsops
, cd9660
, VFCF_READONLY
);
98 MODULE_VERSION(cd9660
, 1);
102 * Called by vfs_mountroot when iso is going to be mounted as root.
105 static int iso_get_ssector (cdev_t dev
);
106 static int iso_mountfs (struct vnode
*devvp
, struct mount
*mp
,
107 struct iso_args
*argp
);
110 * Try to find the start of the last data track on this CD-ROM. This
111 * is used to mount the last session of a multi-session CD. Bail out
112 * and return 0 if we fail, this is always a safe bet.
115 iso_get_ssector(cdev_t dev
)
117 struct ioc_toc_header h
;
118 struct ioc_read_toc_single_entry t
;
121 if (dev_dioctl(dev
, CDIOREADTOCHEADER
, (caddr_t
)&h
, FREAD
,
122 proc0
.p_ucred
, NULL
) != 0)
125 for (i
= h
.ending_track
; i
>= 0; i
--) {
126 t
.address_format
= CD_LBA_FORMAT
;
128 if (dev_dioctl(dev
, CDIOREADTOCENTRY
, (caddr_t
)&t
, FREAD
,
129 proc0
.p_ucred
, NULL
) != 0) {
132 if ((t
.entry
.control
& 4) != 0)
133 /* found a data track */
140 return ntohl(t
.entry
.addr
.lba
);
144 iso_mountroot(struct mount
*mp
)
146 struct iso_args args
;
147 struct vnode
*rootvp
;
150 if ((error
= bdevvp(rootdev
, &rootvp
))) {
151 kprintf("iso_mountroot: can't find rootvp\n");
154 args
.flags
= ISOFSMNT_ROOT
;
156 vn_lock(rootvp
, LK_EXCLUSIVE
| LK_RETRY
);
157 error
= VOP_OPEN(rootvp
, FREAD
, FSCRED
, NULL
);
162 args
.ssector
= iso_get_ssector(rootdev
);
164 VOP_CLOSE(rootvp
, FREAD
);
167 kprintf("iso_mountroot(): using session at block %d\n",
169 if ((error
= iso_mountfs(rootvp
, mp
, &args
)) != 0)
172 cd9660_statfs(mp
, &mp
->mnt_stat
, proc0
.p_ucred
);
182 cd9660_mount(struct mount
*mp
, char *path
, caddr_t data
, struct ucred
*cred
)
185 struct iso_args args
;
189 struct iso_mnt
*imp
= 0;
190 struct nlookupdata nd
;
192 if ((mp
->mnt_flag
& (MNT_ROOTFS
|MNT_UPDATE
)) == MNT_ROOTFS
) {
193 return (iso_mountroot(mp
));
195 if ((error
= copyin(data
, (caddr_t
)&args
, sizeof (struct iso_args
))))
198 if ((mp
->mnt_flag
& MNT_RDONLY
) == 0)
202 * If updating, check whether changing from read-only to
203 * read/write; if there is no device name, that's all we do.
205 if (mp
->mnt_flag
& MNT_UPDATE
) {
206 imp
= VFSTOISOFS(mp
);
208 return (vfs_export(mp
, &imp
->im_export
, &args
.export
));
211 * Not an update, or updating the name: look up the name
212 * and verify that it refers to a sensible block device.
215 error
= nlookup_init(&nd
, args
.fspec
, UIO_USERSPACE
, NLC_FOLLOW
);
217 error
= nlookup(&nd
);
219 error
= cache_vref(&nd
.nl_nch
, nd
.nl_cred
, &devvp
);
224 if (!vn_isdisk(devvp
, &error
)) {
230 * Verify that user has necessary permissions on the device,
231 * or has superuser abilities
234 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
235 error
= VOP_ACCESS(devvp
, accessmode
, cred
);
237 error
= priv_check_cred(cred
, PRIV_ROOT
, 0);
244 if ((mp
->mnt_flag
& MNT_UPDATE
) == 0) {
245 error
= iso_mountfs(devvp
, mp
, &args
);
247 if (devvp
!= imp
->im_devvp
)
248 error
= EINVAL
; /* needs translation */
256 imp
= VFSTOISOFS(mp
);
257 copyinstr(args
.fspec
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1,
259 bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
260 cd9660_statfs(mp
, &mp
->mnt_stat
, cred
);
265 * Common code for mount and mountroot
268 iso_mountfs(struct vnode
*devvp
, struct mount
*mp
, struct iso_args
*argp
)
270 struct iso_mnt
*isomp
= NULL
;
271 struct buf
*bp
= NULL
;
272 struct buf
*pribp
= NULL
, *supbp
= NULL
;
280 struct iso_volume_descriptor
*vdp
= 0;
281 struct iso_primary_descriptor
*pri
= NULL
;
282 struct iso_sierra_primary_descriptor
*pri_sierra
= NULL
;
283 struct iso_supplementary_descriptor
*sup
= NULL
;
284 struct iso_directory_record
*rootp
;
285 int logical_block_size
;
287 if (!(mp
->mnt_flag
& MNT_RDONLY
))
291 * Disallow multiple mounts of the same device.
292 * Disallow mounting of a device that is currently in use
293 * Flush out any old buffers remaining from a previous use.
295 if ((error
= vfs_mountedon(devvp
)))
297 if (vcount(devvp
) > 0)
299 if ((error
= vinvalbuf(devvp
, V_SAVE
, 0, 0)))
302 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
303 error
= VOP_OPEN(devvp
, FREAD
, FSCRED
, NULL
);
308 if (dev
->si_iosize_max
!= 0)
309 mp
->mnt_iosize_max
= dev
->si_iosize_max
;
310 if (mp
->mnt_iosize_max
> MAXPHYS
)
311 mp
->mnt_iosize_max
= MAXPHYS
;
315 /* This is the "logical sector size". The standard says this
316 * should be 2048 or the physical sector size on the device,
317 * whichever is greater. For now, we'll just use a constant.
319 iso_bsize
= ISO_DEFAULT_BLOCK_SIZE
;
322 for (iso_blknum
= 16 + argp
->ssector
;
323 iso_blknum
< 100 + argp
->ssector
;
325 if ((error
= bread(devvp
, (off_t
)iso_blknum
* iso_bsize
,
326 iso_bsize
, &bp
)) != 0)
329 vdp
= (struct iso_volume_descriptor
*)bp
->b_data
;
330 if (bcmp (vdp
->id
, ISO_STANDARD_ID
, sizeof vdp
->id
) != 0) {
331 if (bcmp (vdp
->id_sierra
, ISO_SIERRA_ID
,
332 sizeof vdp
->id
) != 0) {
338 switch (isonum_711 (high_sierra
? vdp
->type_sierra
: vdp
->type
)){
343 pri
= (struct iso_primary_descriptor
*)vdp
;
345 (struct iso_sierra_primary_descriptor
*)vdp
;
349 case ISO_VD_SUPPLEMENTARY
:
353 sup
= (struct iso_supplementary_descriptor
*)vdp
;
355 if (!(argp
->flags
& ISOFSMNT_NOJOLIET
)) {
356 if (bcmp(sup
->escape
, "%/@", 3) == 0)
358 if (bcmp(sup
->escape
, "%/C", 3) == 0)
360 if (bcmp(sup
->escape
, "%/E", 3) == 0)
363 if ((isonum_711 (sup
->flags
) & 1) &&
364 (argp
->flags
& ISOFSMNT_BROKENJOLIET
) == 0)
393 isonum_723 (high_sierra
?
394 pri_sierra
->logical_block_size
:
395 pri
->logical_block_size
);
397 if (logical_block_size
< DEV_BSIZE
|| logical_block_size
> MAXBSIZE
398 || (logical_block_size
& (logical_block_size
- 1)) != 0) {
403 rootp
= (struct iso_directory_record
*)
405 pri_sierra
->root_directory_record
:
406 pri
->root_directory_record
);
408 isomp
= kmalloc(sizeof *isomp
, M_ISOFSMNT
, M_WAITOK
| M_ZERO
);
409 isomp
->logical_block_size
= logical_block_size
;
410 isomp
->volume_space_size
=
411 isonum_733 (high_sierra
?
412 pri_sierra
->volume_space_size
:
413 pri
->volume_space_size
);
414 isomp
->joliet_level
= 0;
416 * Since an ISO9660 multi-session CD can also access previous
417 * sessions, we have to include them into the space consider-
418 * ations. This doesn't yield a very accurate number since
419 * parts of the old sessions might be inaccessible now, but we
420 * can't do much better. This is also important for the NFS
421 * filehandle validation.
423 isomp
->volume_space_size
+= argp
->ssector
;
424 bcopy (rootp
, isomp
->root
, sizeof isomp
->root
);
425 isomp
->root_extent
= isonum_733 (rootp
->extent
);
426 isomp
->root_size
= isonum_733 (rootp
->size
);
428 isomp
->im_bmask
= logical_block_size
- 1;
429 isomp
->im_bshift
= ffs(logical_block_size
) - 1;
431 pribp
->b_flags
|= B_AGE
;
435 mp
->mnt_data
= (qaddr_t
)isomp
;
436 mp
->mnt_stat
.f_fsid
.val
[0] = dev2udev(dev
);
437 mp
->mnt_stat
.f_fsid
.val
[1] = mp
->mnt_vfc
->vfc_typenum
;
438 mp
->mnt_maxsymlinklen
= 0;
439 mp
->mnt_flag
|= MNT_LOCAL
;
440 isomp
->im_mountp
= mp
;
442 isomp
->im_devvp
= devvp
;
444 dev
->si_mountpoint
= mp
;
446 /* Check the Rock Ridge Extention support */
447 if (!(argp
->flags
& ISOFSMNT_NORRIP
)) {
448 if ((error
= bread(isomp
->im_devvp
,
449 lblktooff(isomp
, isomp
->root_extent
+ isonum_711(rootp
->ext_attr_length
)),
450 isomp
->logical_block_size
, &bp
)) != 0)
453 rootp
= (struct iso_directory_record
*)bp
->b_data
;
455 if ((isomp
->rr_skip
= cd9660_rrip_offset(rootp
,isomp
)) < 0) {
456 argp
->flags
|= ISOFSMNT_NORRIP
;
458 argp
->flags
&= ~ISOFSMNT_GENS
;
462 * The contents are valid,
463 * but they will get reread as part of another vnode, so...
465 bp
->b_flags
|= B_AGE
;
469 isomp
->im_flags
= argp
->flags
& (ISOFSMNT_NORRIP
| ISOFSMNT_GENS
|
470 ISOFSMNT_EXTATT
| ISOFSMNT_NOJOLIET
);
473 /* this effectively ignores all the mount flags */
474 log(LOG_INFO
, "cd9660: High Sierra Format\n");
475 isomp
->iso_ftype
= ISO_FTYPE_HIGH_SIERRA
;
477 switch (isomp
->im_flags
&(ISOFSMNT_NORRIP
|ISOFSMNT_GENS
)) {
479 isomp
->iso_ftype
= ISO_FTYPE_DEFAULT
;
481 case ISOFSMNT_GENS
|ISOFSMNT_NORRIP
:
482 isomp
->iso_ftype
= ISO_FTYPE_9660
;
485 log(LOG_INFO
, "cd9660: RockRidge Extension\n");
486 isomp
->iso_ftype
= ISO_FTYPE_RRIP
;
491 /* Decide whether to use the Joliet descriptor */
493 if (isomp
->iso_ftype
!= ISO_FTYPE_RRIP
&& joliet_level
) {
494 log(LOG_INFO
, "cd9660: Joliet Extension (Level %d)\n", joliet_level
);
495 rootp
= (struct iso_directory_record
*)
496 sup
->root_directory_record
;
497 bcopy (rootp
, isomp
->root
, sizeof isomp
->root
);
498 isomp
->root_extent
= isonum_733 (rootp
->extent
);
499 isomp
->root_size
= isonum_733 (rootp
->size
);
500 isomp
->joliet_level
= joliet_level
;
501 supbp
->b_flags
|= B_AGE
;
509 vfs_add_vnodeops(mp
, &cd9660_vnode_vops
, &mp
->mnt_vn_norm_ops
);
510 vfs_add_vnodeops(mp
, &cd9660_spec_vops
, &mp
->mnt_vn_spec_ops
);
511 vfs_add_vnodeops(mp
, &cd9660_fifo_vops
, &mp
->mnt_vn_fifo_ops
);
515 dev
->si_mountpoint
= NULL
;
523 VOP_CLOSE(devvp
, FREAD
);
525 kfree((caddr_t
)isomp
, M_ISOFSMNT
);
526 mp
->mnt_data
= (qaddr_t
)0;
532 * unmount system call
535 cd9660_unmount(struct mount
*mp
, int mntflags
)
537 struct iso_mnt
*isomp
;
538 int error
, flags
= 0;
540 if (mntflags
& MNT_FORCE
)
547 if ((error
= vflush(mp
, 0, flags
)))
550 isomp
= VFSTOISOFS(mp
);
552 isomp
->im_devvp
->v_rdev
->si_mountpoint
= NULL
;
553 error
= VOP_CLOSE(isomp
->im_devvp
, FREAD
);
554 vrele(isomp
->im_devvp
);
555 kfree((caddr_t
)isomp
, M_ISOFSMNT
);
556 mp
->mnt_data
= (qaddr_t
)0;
557 mp
->mnt_flag
&= ~MNT_LOCAL
;
562 * Return root of a filesystem
565 cd9660_root(struct mount
*mp
, struct vnode
**vpp
)
567 struct iso_mnt
*imp
= VFSTOISOFS(mp
);
568 struct iso_directory_record
*dp
=
569 (struct iso_directory_record
*)imp
->root
;
570 ino_t ino
= isodirino(dp
, imp
);
573 * With RRIP we must use the `.' entry of the root directory.
574 * Simply tell vget, that it's a relocated directory.
576 return (cd9660_vget_internal(mp
, ino
, vpp
,
577 imp
->iso_ftype
== ISO_FTYPE_RRIP
, dp
));
581 * Get file system statistics.
584 cd9660_statfs(struct mount
*mp
, struct statfs
*sbp
, struct ucred
*cred
)
586 struct iso_mnt
*isomp
;
588 isomp
= VFSTOISOFS(mp
);
590 sbp
->f_bsize
= isomp
->logical_block_size
;
591 sbp
->f_iosize
= sbp
->f_bsize
; /* XXX */
592 sbp
->f_blocks
= isomp
->volume_space_size
;
593 sbp
->f_bfree
= 0; /* total free blocks */
594 sbp
->f_bavail
= 0; /* blocks free for non superuser */
595 sbp
->f_files
= 0; /* total files */
596 sbp
->f_ffree
= 0; /* free file nodes */
597 if (sbp
!= &mp
->mnt_stat
) {
598 sbp
->f_type
= mp
->mnt_vfc
->vfc_typenum
;
599 bcopy(mp
->mnt_stat
.f_mntfromname
, sbp
->f_mntfromname
, MNAMELEN
);
605 * File handle to vnode
607 * Have to be really careful about stale file handles:
608 * - check that the inode number is in range
609 * - call iget() to get the locked inode
610 * - check for an unallocated inode (i_mode == 0)
611 * - check that the generation number matches
623 cd9660_fhtovp(struct mount
*mp
, struct vnode
*rootvp
,
624 struct fid
*fhp
, struct vnode
**vpp
)
626 struct ifid
*ifhp
= (struct ifid
*)fhp
;
632 kprintf("fhtovp: ino %d, start %ld\n",
633 ifhp
->ifid_ino
, ifhp
->ifid_start
);
636 if ((error
= VFS_VGET(mp
, NULL
, ifhp
->ifid_ino
, &nvp
)) != 0) {
641 if (ip
->inode
.iso_mode
== 0) {
651 cd9660_checkexp(struct mount
*mp
, struct sockaddr
*nam
, int *exflagsp
,
652 struct ucred
**credanonp
)
657 imp
= VFSTOISOFS(mp
);
660 * Get the export permission structure for this <mp, client> tuple.
662 np
= vfs_export_lookup(mp
, &imp
->im_export
, nam
);
666 *exflagsp
= np
->netc_exflags
;
667 *credanonp
= &np
->netc_anon
;
672 cd9660_vget(struct mount
*mp
, struct vnode
*dvp
, ino_t ino
, struct vnode
**vpp
)
677 * It would be nice if we didn't always set the `relocated' flag
678 * and force the extra read, but I don't want to think about fixing
681 return (cd9660_vget_internal(mp
, ino
, vpp
,
683 VFSTOISOFS(mp
)->iso_ftype
== ISO_FTYPE_RRIP
,
691 cd9660_vget_internal(struct mount
*mp
, ino_t ino
, struct vnode
**vpp
,
692 int relocated
, struct iso_directory_record
*isodir
)
701 imp
= VFSTOISOFS(mp
);
704 if ((*vpp
= cd9660_ihashget(dev
, ino
)) != NULLVP
)
707 /* Allocate a new vnode/iso_node. */
708 error
= getnewvnode(VT_ISOFS
, mp
, &vp
, 0, 0);
713 MALLOC(ip
, struct iso_node
*, sizeof(struct iso_node
), M_ISOFSNODE
,
720 * Insert it into the inode hash table and check for a collision.
721 * If a collision occurs, throw away the vnode and try again.
723 if (cd9660_ihashins(ip
) != 0) {
724 kprintf("debug: cd9660 ihashins collision, retrying\n");
726 kfree(ip
, M_ISOFSNODE
);
731 if (isodir
== NULL
) {
734 lbn
= lblkno(imp
, ino
);
735 if (lbn
>= imp
->volume_space_size
) {
737 kprintf("fhtovp: lbn exceed volume space %d\n", lbn
);
741 off
= blkoff(imp
, ino
);
742 if (off
+ ISO_DIRECTORY_RECORD_SIZE
> imp
->logical_block_size
) {
744 kprintf("fhtovp: crosses block boundary %d\n",
745 off
+ ISO_DIRECTORY_RECORD_SIZE
);
749 error
= bread(imp
->im_devvp
,
751 imp
->logical_block_size
, &bp
);
755 kprintf("fhtovp: bread error %d\n",error
);
758 isodir
= (struct iso_directory_record
*)(bp
->b_data
+ off
);
760 if (off
+ isonum_711(isodir
->length
) >
761 imp
->logical_block_size
) {
765 kprintf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
766 off
+isonum_711(isodir
->length
), off
,
767 isonum_711(isodir
->length
));
772 if (isonum_733(isodir
->extent
) +
773 isonum_711(isodir
->ext_attr_length
) != ifhp
->ifid_start
) {
776 kprintf("fhtovp: file start miss %d vs %d\n",
777 isonum_733(isodir
->extent
) + isonum_711(isodir
->ext_attr_length
),
786 ip
->i_devvp
= imp
->im_devvp
;
791 * On relocated directories we must
792 * read the `.' entry out of a dir.
794 ip
->iso_start
= ino
>> imp
->im_bshift
;
797 if ((error
= cd9660_devblkatoff(vp
, (off_t
)0, NULL
, &bp
)) != 0) {
801 isodir
= (struct iso_directory_record
*)bp
->b_data
;
804 ip
->iso_extent
= isonum_733(isodir
->extent
);
805 ip
->i_size
= isonum_733(isodir
->size
);
806 ip
->iso_start
= isonum_711(isodir
->ext_attr_length
) + ip
->iso_extent
;
809 * Setup time stamp, attribute
812 switch (imp
->iso_ftype
) {
813 default: /* ISO_FTYPE_9660 */
817 if ((imp
->im_flags
& ISOFSMNT_EXTATT
)
818 && (off
= isonum_711(isodir
->ext_attr_length
)))
819 cd9660_devblkatoff(vp
, (off_t
)-(off
<< imp
->im_bshift
), NULL
,
823 cd9660_defattr(isodir
, ip
, bp2
, ISO_FTYPE_9660
);
824 cd9660_deftstamp(isodir
, ip
, bp2
, ISO_FTYPE_9660
);
830 cd9660_rrip_analyze(isodir
, ip
, imp
);
838 * Initialize the associated vnode
840 vp
->v_type
= IFTOVT(ip
->inode
.iso_mode
);
842 switch (vp
->v_type
) {
844 vp
->v_ops
= &mp
->mnt_vn_fifo_ops
;
848 vp
->v_ops
= &mp
->mnt_vn_spec_ops
;
849 addaliasu(vp
, umajor(ip
->inode
.iso_rdev
),
850 uminor(ip
->inode
.iso_rdev
));
854 vinitvmio(vp
, ip
->i_size
);
860 if (ip
->iso_extent
== imp
->root_extent
)
864 * Return the locked and refd vp
871 * Vnode pointer to File handle
875 cd9660_vptofh(struct vnode
*vp
, struct fid
*fhp
)
877 struct iso_node
*ip
= VTOI(vp
);
880 ifhp
= (struct ifid
*)fhp
;
881 ifhp
->ifid_len
= sizeof(struct ifid
);
883 ifhp
->ifid_ino
= ip
->i_number
;
884 ifhp
->ifid_start
= ip
->iso_start
;
887 kprintf("vptofh: ino %d, start %ld\n",
888 ifhp
->ifid_ino
,ifhp
->ifid_start
);