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.45 2008/01/05 14:02:41 swildner Exp $
43 #include <sys/param.h>
44 #include <sys/systm.h>
46 #include <sys/nlookup.h>
47 #include <sys/kernel.h>
48 #include <sys/vnode.h>
49 #include <sys/mount.h>
53 #include <sys/fcntl.h>
54 #include <sys/malloc.h>
56 #include <sys/syslog.h>
58 #include <vm/vm_zone.h>
62 #include "cd9660_node.h"
63 #include "cd9660_mount.h"
65 extern struct vop_ops cd9660_vnode_vops
;
66 extern struct vop_ops cd9660_spec_vops
;
67 extern struct vop_ops cd9660_fifo_vops
;
69 MALLOC_DEFINE(M_ISOFSMNT
, "ISOFS mount", "ISOFS mount structure");
70 MALLOC_DEFINE(M_ISOFSNODE
, "ISOFS node", "ISOFS vnode private part");
72 static int cd9660_mount (struct mount
*, char *, caddr_t
, struct ucred
*);
73 static int cd9660_unmount (struct mount
*, int);
74 static int cd9660_root (struct mount
*, struct vnode
**);
75 static int cd9660_statfs (struct mount
*, struct statfs
*, struct ucred
*);
76 static int cd9660_vget (struct mount
*, ino_t
, struct vnode
**);
77 static int cd9660_fhtovp (struct mount
*, struct fid
*, struct vnode
**);
78 static int cd9660_checkexp (struct mount
*, struct sockaddr
*,
79 int *, struct ucred
**);
80 static int cd9660_vptofh (struct vnode
*, struct fid
*);
82 static struct vfsops cd9660_vfsops
= {
83 .vfs_mount
= cd9660_mount
,
84 .vfs_unmount
= cd9660_unmount
,
85 .vfs_root
= cd9660_root
,
86 .vfs_statfs
= cd9660_statfs
,
87 .vfs_sync
= vfs_stdsync
,
88 .vfs_vget
= cd9660_vget
,
89 .vfs_fhtovp
= cd9660_fhtovp
,
90 .vfs_checkexp
= cd9660_checkexp
,
91 .vfs_vptofh
= cd9660_vptofh
,
92 .vfs_init
= cd9660_init
,
93 .vfs_uninit
= cd9660_uninit
,
95 VFS_SET(cd9660_vfsops
, cd9660
, VFCF_READONLY
);
96 MODULE_VERSION(cd9660
, 1);
100 * Called by vfs_mountroot when iso is going to be mounted as root.
103 static int iso_get_ssector (cdev_t dev
);
104 static int iso_mountfs (struct vnode
*devvp
, struct mount
*mp
,
105 struct iso_args
*argp
);
108 * Try to find the start of the last data track on this CD-ROM. This
109 * is used to mount the last session of a multi-session CD. Bail out
110 * and return 0 if we fail, this is always a safe bet.
113 iso_get_ssector(cdev_t dev
)
115 struct ioc_toc_header h
;
116 struct ioc_read_toc_single_entry t
;
119 if (dev_dioctl(dev
, CDIOREADTOCHEADER
, (caddr_t
)&h
, FREAD
, proc0
.p_ucred
) != 0)
122 for (i
= h
.ending_track
; i
>= 0; i
--) {
123 t
.address_format
= CD_LBA_FORMAT
;
125 if (dev_dioctl(dev
, CDIOREADTOCENTRY
, (caddr_t
)&t
, FREAD
, proc0
.p_ucred
) != 0) {
128 if ((t
.entry
.control
& 4) != 0)
129 /* found a data track */
136 return ntohl(t
.entry
.addr
.lba
);
140 iso_mountroot(struct mount
*mp
)
142 struct iso_args args
;
143 struct vnode
*rootvp
;
146 if ((error
= bdevvp(rootdev
, &rootvp
))) {
147 kprintf("iso_mountroot: can't find rootvp\n");
150 args
.flags
= ISOFSMNT_ROOT
;
152 vn_lock(rootvp
, LK_EXCLUSIVE
| LK_RETRY
);
153 error
= VOP_OPEN(rootvp
, FREAD
, FSCRED
, NULL
);
158 args
.ssector
= iso_get_ssector(rootdev
);
160 VOP_CLOSE(rootvp
, FREAD
);
163 kprintf("iso_mountroot(): using session at block %d\n",
165 if ((error
= iso_mountfs(rootvp
, mp
, &args
)) != 0)
168 cd9660_statfs(mp
, &mp
->mnt_stat
, proc0
.p_ucred
);
178 cd9660_mount(struct mount
*mp
, char *path
, caddr_t data
, struct ucred
*cred
)
181 struct iso_args args
;
185 struct iso_mnt
*imp
= 0;
186 struct nlookupdata nd
;
188 if ((mp
->mnt_flag
& (MNT_ROOTFS
|MNT_UPDATE
)) == MNT_ROOTFS
) {
189 return (iso_mountroot(mp
));
191 if ((error
= copyin(data
, (caddr_t
)&args
, sizeof (struct iso_args
))))
194 if ((mp
->mnt_flag
& MNT_RDONLY
) == 0)
198 * If updating, check whether changing from read-only to
199 * read/write; if there is no device name, that's all we do.
201 if (mp
->mnt_flag
& MNT_UPDATE
) {
202 imp
= VFSTOISOFS(mp
);
204 return (vfs_export(mp
, &imp
->im_export
, &args
.export
));
207 * Not an update, or updating the name: look up the name
208 * and verify that it refers to a sensible block device.
211 error
= nlookup_init(&nd
, args
.fspec
, UIO_USERSPACE
, NLC_FOLLOW
);
213 error
= nlookup(&nd
);
215 error
= cache_vref(&nd
.nl_nch
, nd
.nl_cred
, &devvp
);
220 if (!vn_isdisk(devvp
, &error
)) {
226 * Verify that user has necessary permissions on the device,
227 * or has superuser abilities
230 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
231 error
= VOP_ACCESS(devvp
, accessmode
, cred
);
233 error
= suser_cred(cred
, 0);
240 if ((mp
->mnt_flag
& MNT_UPDATE
) == 0) {
241 error
= iso_mountfs(devvp
, mp
, &args
);
243 if (devvp
!= imp
->im_devvp
)
244 error
= EINVAL
; /* needs translation */
252 imp
= VFSTOISOFS(mp
);
253 copyinstr(args
.fspec
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1,
255 bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
256 cd9660_statfs(mp
, &mp
->mnt_stat
, cred
);
261 * Common code for mount and mountroot
264 iso_mountfs(struct vnode
*devvp
, struct mount
*mp
, struct iso_args
*argp
)
266 struct iso_mnt
*isomp
= NULL
;
267 struct buf
*bp
= NULL
;
268 struct buf
*pribp
= NULL
, *supbp
= NULL
;
276 struct iso_volume_descriptor
*vdp
= 0;
277 struct iso_primary_descriptor
*pri
= NULL
;
278 struct iso_sierra_primary_descriptor
*pri_sierra
= NULL
;
279 struct iso_supplementary_descriptor
*sup
= NULL
;
280 struct iso_directory_record
*rootp
;
281 int logical_block_size
;
283 if (!(mp
->mnt_flag
& MNT_RDONLY
))
287 * Disallow multiple mounts of the same device.
288 * Disallow mounting of a device that is currently in use
289 * Flush out any old buffers remaining from a previous use.
291 if ((error
= vfs_mountedon(devvp
)))
293 if (count_udev(devvp
->v_umajor
, devvp
->v_uminor
) > 0)
295 if ((error
= vinvalbuf(devvp
, V_SAVE
, 0, 0)))
298 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
299 error
= VOP_OPEN(devvp
, FREAD
, FSCRED
, NULL
);
304 if (dev
->si_iosize_max
!= 0)
305 mp
->mnt_iosize_max
= dev
->si_iosize_max
;
306 if (mp
->mnt_iosize_max
> MAXPHYS
)
307 mp
->mnt_iosize_max
= MAXPHYS
;
311 /* This is the "logical sector size". The standard says this
312 * should be 2048 or the physical sector size on the device,
313 * whichever is greater. For now, we'll just use a constant.
315 iso_bsize
= ISO_DEFAULT_BLOCK_SIZE
;
318 for (iso_blknum
= 16 + argp
->ssector
;
319 iso_blknum
< 100 + argp
->ssector
;
321 if ((error
= bread(devvp
, (off_t
)iso_blknum
* iso_bsize
,
322 iso_bsize
, &bp
)) != 0)
325 vdp
= (struct iso_volume_descriptor
*)bp
->b_data
;
326 if (bcmp (vdp
->id
, ISO_STANDARD_ID
, sizeof vdp
->id
) != 0) {
327 if (bcmp (vdp
->id_sierra
, ISO_SIERRA_ID
,
328 sizeof vdp
->id
) != 0) {
334 switch (isonum_711 (high_sierra
? vdp
->type_sierra
: vdp
->type
)){
339 pri
= (struct iso_primary_descriptor
*)vdp
;
341 (struct iso_sierra_primary_descriptor
*)vdp
;
345 case ISO_VD_SUPPLEMENTARY
:
349 sup
= (struct iso_supplementary_descriptor
*)vdp
;
351 if (!(argp
->flags
& ISOFSMNT_NOJOLIET
)) {
352 if (bcmp(sup
->escape
, "%/@", 3) == 0)
354 if (bcmp(sup
->escape
, "%/C", 3) == 0)
356 if (bcmp(sup
->escape
, "%/E", 3) == 0)
359 if ((isonum_711 (sup
->flags
) & 1) &&
360 (argp
->flags
& ISOFSMNT_BROKENJOLIET
) == 0)
389 isonum_723 (high_sierra
?
390 pri_sierra
->logical_block_size
:
391 pri
->logical_block_size
);
393 if (logical_block_size
< DEV_BSIZE
|| logical_block_size
> MAXBSIZE
394 || (logical_block_size
& (logical_block_size
- 1)) != 0) {
399 rootp
= (struct iso_directory_record
*)
401 pri_sierra
->root_directory_record
:
402 pri
->root_directory_record
);
404 isomp
= kmalloc(sizeof *isomp
, M_ISOFSMNT
, M_WAITOK
| M_ZERO
);
405 isomp
->logical_block_size
= logical_block_size
;
406 isomp
->volume_space_size
=
407 isonum_733 (high_sierra
?
408 pri_sierra
->volume_space_size
:
409 pri
->volume_space_size
);
410 isomp
->joliet_level
= 0;
412 * Since an ISO9660 multi-session CD can also access previous
413 * sessions, we have to include them into the space consider-
414 * ations. This doesn't yield a very accurate number since
415 * parts of the old sessions might be inaccessible now, but we
416 * can't do much better. This is also important for the NFS
417 * filehandle validation.
419 isomp
->volume_space_size
+= argp
->ssector
;
420 bcopy (rootp
, isomp
->root
, sizeof isomp
->root
);
421 isomp
->root_extent
= isonum_733 (rootp
->extent
);
422 isomp
->root_size
= isonum_733 (rootp
->size
);
424 isomp
->im_bmask
= logical_block_size
- 1;
425 isomp
->im_bshift
= ffs(logical_block_size
) - 1;
427 pribp
->b_flags
|= B_AGE
;
431 mp
->mnt_data
= (qaddr_t
)isomp
;
432 mp
->mnt_stat
.f_fsid
.val
[0] = dev2udev(dev
);
433 mp
->mnt_stat
.f_fsid
.val
[1] = mp
->mnt_vfc
->vfc_typenum
;
434 mp
->mnt_maxsymlinklen
= 0;
435 mp
->mnt_flag
|= MNT_LOCAL
;
436 isomp
->im_mountp
= mp
;
438 isomp
->im_devvp
= devvp
;
440 dev
->si_mountpoint
= mp
;
442 /* Check the Rock Ridge Extention support */
443 if (!(argp
->flags
& ISOFSMNT_NORRIP
)) {
444 if ((error
= bread(isomp
->im_devvp
,
445 lblktooff(isomp
, isomp
->root_extent
+ isonum_711(rootp
->ext_attr_length
)),
446 isomp
->logical_block_size
, &bp
)) != 0)
449 rootp
= (struct iso_directory_record
*)bp
->b_data
;
451 if ((isomp
->rr_skip
= cd9660_rrip_offset(rootp
,isomp
)) < 0) {
452 argp
->flags
|= ISOFSMNT_NORRIP
;
454 argp
->flags
&= ~ISOFSMNT_GENS
;
458 * The contents are valid,
459 * but they will get reread as part of another vnode, so...
461 bp
->b_flags
|= B_AGE
;
465 isomp
->im_flags
= argp
->flags
& (ISOFSMNT_NORRIP
| ISOFSMNT_GENS
|
466 ISOFSMNT_EXTATT
| ISOFSMNT_NOJOLIET
);
469 /* this effectively ignores all the mount flags */
470 log(LOG_INFO
, "cd9660: High Sierra Format\n");
471 isomp
->iso_ftype
= ISO_FTYPE_HIGH_SIERRA
;
473 switch (isomp
->im_flags
&(ISOFSMNT_NORRIP
|ISOFSMNT_GENS
)) {
475 isomp
->iso_ftype
= ISO_FTYPE_DEFAULT
;
477 case ISOFSMNT_GENS
|ISOFSMNT_NORRIP
:
478 isomp
->iso_ftype
= ISO_FTYPE_9660
;
481 log(LOG_INFO
, "cd9660: RockRidge Extension\n");
482 isomp
->iso_ftype
= ISO_FTYPE_RRIP
;
487 /* Decide whether to use the Joliet descriptor */
489 if (isomp
->iso_ftype
!= ISO_FTYPE_RRIP
&& joliet_level
) {
490 log(LOG_INFO
, "cd9660: Joliet Extension (Level %d)\n", joliet_level
);
491 rootp
= (struct iso_directory_record
*)
492 sup
->root_directory_record
;
493 bcopy (rootp
, isomp
->root
, sizeof isomp
->root
);
494 isomp
->root_extent
= isonum_733 (rootp
->extent
);
495 isomp
->root_size
= isonum_733 (rootp
->size
);
496 isomp
->joliet_level
= joliet_level
;
497 supbp
->b_flags
|= B_AGE
;
505 vfs_add_vnodeops(mp
, &cd9660_vnode_vops
, &mp
->mnt_vn_norm_ops
);
506 vfs_add_vnodeops(mp
, &cd9660_spec_vops
, &mp
->mnt_vn_spec_ops
);
507 vfs_add_vnodeops(mp
, &cd9660_fifo_vops
, &mp
->mnt_vn_fifo_ops
);
511 dev
->si_mountpoint
= NULL
;
519 VOP_CLOSE(devvp
, FREAD
);
521 kfree((caddr_t
)isomp
, M_ISOFSMNT
);
522 mp
->mnt_data
= (qaddr_t
)0;
528 * unmount system call
531 cd9660_unmount(struct mount
*mp
, int mntflags
)
533 struct iso_mnt
*isomp
;
534 int error
, flags
= 0;
536 if (mntflags
& MNT_FORCE
)
543 if ((error
= vflush(mp
, 0, flags
)))
546 isomp
= VFSTOISOFS(mp
);
548 isomp
->im_devvp
->v_rdev
->si_mountpoint
= NULL
;
549 error
= VOP_CLOSE(isomp
->im_devvp
, FREAD
);
550 vrele(isomp
->im_devvp
);
551 kfree((caddr_t
)isomp
, M_ISOFSMNT
);
552 mp
->mnt_data
= (qaddr_t
)0;
553 mp
->mnt_flag
&= ~MNT_LOCAL
;
558 * Return root of a filesystem
561 cd9660_root(struct mount
*mp
, struct vnode
**vpp
)
563 struct iso_mnt
*imp
= VFSTOISOFS(mp
);
564 struct iso_directory_record
*dp
=
565 (struct iso_directory_record
*)imp
->root
;
566 ino_t ino
= isodirino(dp
, imp
);
569 * With RRIP we must use the `.' entry of the root directory.
570 * Simply tell vget, that it's a relocated directory.
572 return (cd9660_vget_internal(mp
, ino
, vpp
,
573 imp
->iso_ftype
== ISO_FTYPE_RRIP
, dp
));
577 * Get file system statistics.
580 cd9660_statfs(struct mount
*mp
, struct statfs
*sbp
, struct ucred
*cred
)
582 struct iso_mnt
*isomp
;
584 isomp
= VFSTOISOFS(mp
);
586 sbp
->f_bsize
= isomp
->logical_block_size
;
587 sbp
->f_iosize
= sbp
->f_bsize
; /* XXX */
588 sbp
->f_blocks
= isomp
->volume_space_size
;
589 sbp
->f_bfree
= 0; /* total free blocks */
590 sbp
->f_bavail
= 0; /* blocks free for non superuser */
591 sbp
->f_files
= 0; /* total files */
592 sbp
->f_ffree
= 0; /* free file nodes */
593 if (sbp
!= &mp
->mnt_stat
) {
594 sbp
->f_type
= mp
->mnt_vfc
->vfc_typenum
;
595 bcopy(mp
->mnt_stat
.f_mntfromname
, sbp
->f_mntfromname
, MNAMELEN
);
601 * File handle to vnode
603 * Have to be really careful about stale file handles:
604 * - check that the inode number is in range
605 * - call iget() to get the locked inode
606 * - check for an unallocated inode (i_mode == 0)
607 * - check that the generation number matches
619 cd9660_fhtovp(struct mount
*mp
, struct fid
*fhp
, struct vnode
**vpp
)
621 struct ifid
*ifhp
= (struct ifid
*)fhp
;
627 kprintf("fhtovp: ino %d, start %ld\n",
628 ifhp
->ifid_ino
, ifhp
->ifid_start
);
631 if ((error
= VFS_VGET(mp
, ifhp
->ifid_ino
, &nvp
)) != 0) {
636 if (ip
->inode
.iso_mode
== 0) {
646 cd9660_checkexp(struct mount
*mp
, struct sockaddr
*nam
, int *exflagsp
,
647 struct ucred
**credanonp
)
652 imp
= VFSTOISOFS(mp
);
655 * Get the export permission structure for this <mp, client> tuple.
657 np
= vfs_export_lookup(mp
, &imp
->im_export
, nam
);
661 *exflagsp
= np
->netc_exflags
;
662 *credanonp
= &np
->netc_anon
;
667 cd9660_vget(struct mount
*mp
, ino_t ino
, struct vnode
**vpp
)
672 * It would be nice if we didn't always set the `relocated' flag
673 * and force the extra read, but I don't want to think about fixing
676 return (cd9660_vget_internal(mp
, ino
, vpp
,
678 VFSTOISOFS(mp
)->iso_ftype
== ISO_FTYPE_RRIP
,
682 (struct iso_directory_record
*)0));
686 cd9660_vget_internal(struct mount
*mp
, ino_t ino
, struct vnode
**vpp
,
687 int relocated
, struct iso_directory_record
*isodir
)
696 imp
= VFSTOISOFS(mp
);
699 if ((*vpp
= cd9660_ihashget(dev
, ino
)) != NULLVP
)
702 /* Allocate a new vnode/iso_node. */
703 error
= getnewvnode(VT_ISOFS
, mp
, &vp
, 0, 0);
708 MALLOC(ip
, struct iso_node
*, sizeof(struct iso_node
), M_ISOFSNODE
,
715 * Insert it into the inode hash table and check for a collision.
716 * If a collision occurs, throw away the vnode and try again.
718 if (cd9660_ihashins(ip
) != 0) {
719 kprintf("debug: cd9660 ihashins collision, retrying\n");
721 kfree(ip
, M_ISOFSNODE
);
726 if (isodir
== NULL
) {
729 lbn
= lblkno(imp
, ino
);
730 if (lbn
>= imp
->volume_space_size
) {
732 kprintf("fhtovp: lbn exceed volume space %d\n", lbn
);
736 off
= blkoff(imp
, ino
);
737 if (off
+ ISO_DIRECTORY_RECORD_SIZE
> imp
->logical_block_size
) {
739 kprintf("fhtovp: crosses block boundary %d\n",
740 off
+ ISO_DIRECTORY_RECORD_SIZE
);
744 error
= bread(imp
->im_devvp
,
746 imp
->logical_block_size
, &bp
);
750 kprintf("fhtovp: bread error %d\n",error
);
753 isodir
= (struct iso_directory_record
*)(bp
->b_data
+ off
);
755 if (off
+ isonum_711(isodir
->length
) >
756 imp
->logical_block_size
) {
760 kprintf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
761 off
+isonum_711(isodir
->length
), off
,
762 isonum_711(isodir
->length
));
767 if (isonum_733(isodir
->extent
) +
768 isonum_711(isodir
->ext_attr_length
) != ifhp
->ifid_start
) {
771 kprintf("fhtovp: file start miss %d vs %d\n",
772 isonum_733(isodir
->extent
) + isonum_711(isodir
->ext_attr_length
),
781 ip
->i_devvp
= imp
->im_devvp
;
786 * On relocated directories we must
787 * read the `.' entry out of a dir.
789 ip
->iso_start
= ino
>> imp
->im_bshift
;
792 if ((error
= cd9660_devblkatoff(vp
, (off_t
)0, NULL
, &bp
)) != 0) {
796 isodir
= (struct iso_directory_record
*)bp
->b_data
;
799 ip
->iso_extent
= isonum_733(isodir
->extent
);
800 ip
->i_size
= isonum_733(isodir
->size
);
801 ip
->iso_start
= isonum_711(isodir
->ext_attr_length
) + ip
->iso_extent
;
804 * Setup time stamp, attribute
807 switch (imp
->iso_ftype
) {
808 default: /* ISO_FTYPE_9660 */
812 if ((imp
->im_flags
& ISOFSMNT_EXTATT
)
813 && (off
= isonum_711(isodir
->ext_attr_length
)))
814 cd9660_devblkatoff(vp
, (off_t
)-(off
<< imp
->im_bshift
), NULL
,
818 cd9660_defattr(isodir
, ip
, bp2
, ISO_FTYPE_9660
);
819 cd9660_deftstamp(isodir
, ip
, bp2
, ISO_FTYPE_9660
);
825 cd9660_rrip_analyze(isodir
, ip
, imp
);
833 * Initialize the associated vnode
835 vp
->v_type
= IFTOVT(ip
->inode
.iso_mode
);
837 switch (vp
->v_type
) {
839 vp
->v_ops
= &mp
->mnt_vn_fifo_ops
;
843 vp
->v_ops
= &mp
->mnt_vn_spec_ops
;
844 addaliasu(vp
, umajor(ip
->inode
.iso_rdev
),
845 uminor(ip
->inode
.iso_rdev
));
849 vinitvmio(vp
, ip
->i_size
);
855 if (ip
->iso_extent
== imp
->root_extent
)
859 * Return the locked and refd vp
866 * Vnode pointer to File handle
870 cd9660_vptofh(struct vnode
*vp
, struct fid
*fhp
)
872 struct iso_node
*ip
= VTOI(vp
);
875 ifhp
= (struct ifid
*)fhp
;
876 ifhp
->ifid_len
= sizeof(struct ifid
);
878 ifhp
->ifid_ino
= ip
->i_number
;
879 ifhp
->ifid_start
= ip
->iso_start
;
882 kprintf("vptofh: ino %d, start %ld\n",
883 ifhp
->ifid_ino
,ifhp
->ifid_start
);