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.4.1 2008/09/25 02:20:51 dillon 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 vnode
*rootvp
,
78 struct fid
*, struct vnode
**);
79 static int cd9660_checkexp (struct mount
*, struct sockaddr
*,
80 int *, struct ucred
**);
81 static int cd9660_vptofh (struct vnode
*, struct fid
*);
83 static struct vfsops cd9660_vfsops
= {
84 .vfs_mount
= cd9660_mount
,
85 .vfs_unmount
= cd9660_unmount
,
86 .vfs_root
= cd9660_root
,
87 .vfs_statfs
= cd9660_statfs
,
88 .vfs_sync
= vfs_stdsync
,
89 .vfs_vget
= cd9660_vget
,
90 .vfs_fhtovp
= cd9660_fhtovp
,
91 .vfs_checkexp
= cd9660_checkexp
,
92 .vfs_vptofh
= cd9660_vptofh
,
93 .vfs_init
= cd9660_init
,
94 .vfs_uninit
= cd9660_uninit
,
96 VFS_SET(cd9660_vfsops
, cd9660
, VFCF_READONLY
);
97 MODULE_VERSION(cd9660
, 1);
101 * Called by vfs_mountroot when iso is going to be mounted as root.
104 static int iso_get_ssector (cdev_t dev
);
105 static int iso_mountfs (struct vnode
*devvp
, struct mount
*mp
,
106 struct iso_args
*argp
);
109 * Try to find the start of the last data track on this CD-ROM. This
110 * is used to mount the last session of a multi-session CD. Bail out
111 * and return 0 if we fail, this is always a safe bet.
114 iso_get_ssector(cdev_t dev
)
116 struct ioc_toc_header h
;
117 struct ioc_read_toc_single_entry t
;
120 if (dev_dioctl(dev
, CDIOREADTOCHEADER
, (caddr_t
)&h
, FREAD
, proc0
.p_ucred
) != 0)
123 for (i
= h
.ending_track
; i
>= 0; i
--) {
124 t
.address_format
= CD_LBA_FORMAT
;
126 if (dev_dioctl(dev
, CDIOREADTOCENTRY
, (caddr_t
)&t
, FREAD
, proc0
.p_ucred
) != 0) {
129 if ((t
.entry
.control
& 4) != 0)
130 /* found a data track */
137 return ntohl(t
.entry
.addr
.lba
);
141 iso_mountroot(struct mount
*mp
)
143 struct iso_args args
;
144 struct vnode
*rootvp
;
147 if ((error
= bdevvp(rootdev
, &rootvp
))) {
148 kprintf("iso_mountroot: can't find rootvp\n");
151 args
.flags
= ISOFSMNT_ROOT
;
153 vn_lock(rootvp
, LK_EXCLUSIVE
| LK_RETRY
);
154 error
= VOP_OPEN(rootvp
, FREAD
, FSCRED
, NULL
);
159 args
.ssector
= iso_get_ssector(rootdev
);
161 VOP_CLOSE(rootvp
, FREAD
);
164 kprintf("iso_mountroot(): using session at block %d\n",
166 if ((error
= iso_mountfs(rootvp
, mp
, &args
)) != 0)
169 cd9660_statfs(mp
, &mp
->mnt_stat
, proc0
.p_ucred
);
179 cd9660_mount(struct mount
*mp
, char *path
, caddr_t data
, struct ucred
*cred
)
182 struct iso_args args
;
186 struct iso_mnt
*imp
= 0;
187 struct nlookupdata nd
;
189 if ((mp
->mnt_flag
& (MNT_ROOTFS
|MNT_UPDATE
)) == MNT_ROOTFS
) {
190 return (iso_mountroot(mp
));
192 if ((error
= copyin(data
, (caddr_t
)&args
, sizeof (struct iso_args
))))
195 if ((mp
->mnt_flag
& MNT_RDONLY
) == 0)
199 * If updating, check whether changing from read-only to
200 * read/write; if there is no device name, that's all we do.
202 if (mp
->mnt_flag
& MNT_UPDATE
) {
203 imp
= VFSTOISOFS(mp
);
205 return (vfs_export(mp
, &imp
->im_export
, &args
.export
));
208 * Not an update, or updating the name: look up the name
209 * and verify that it refers to a sensible block device.
212 error
= nlookup_init(&nd
, args
.fspec
, UIO_USERSPACE
, NLC_FOLLOW
);
214 error
= nlookup(&nd
);
216 error
= cache_vref(&nd
.nl_nch
, nd
.nl_cred
, &devvp
);
221 if (!vn_isdisk(devvp
, &error
)) {
227 * Verify that user has necessary permissions on the device,
228 * or has superuser abilities
231 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
232 error
= VOP_ACCESS(devvp
, accessmode
, cred
);
234 error
= suser_cred(cred
, 0);
241 if ((mp
->mnt_flag
& MNT_UPDATE
) == 0) {
242 error
= iso_mountfs(devvp
, mp
, &args
);
244 if (devvp
!= imp
->im_devvp
)
245 error
= EINVAL
; /* needs translation */
253 imp
= VFSTOISOFS(mp
);
254 copyinstr(args
.fspec
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1,
256 bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
257 cd9660_statfs(mp
, &mp
->mnt_stat
, cred
);
262 * Common code for mount and mountroot
265 iso_mountfs(struct vnode
*devvp
, struct mount
*mp
, struct iso_args
*argp
)
267 struct iso_mnt
*isomp
= NULL
;
268 struct buf
*bp
= NULL
;
269 struct buf
*pribp
= NULL
, *supbp
= NULL
;
277 struct iso_volume_descriptor
*vdp
= 0;
278 struct iso_primary_descriptor
*pri
= NULL
;
279 struct iso_sierra_primary_descriptor
*pri_sierra
= NULL
;
280 struct iso_supplementary_descriptor
*sup
= NULL
;
281 struct iso_directory_record
*rootp
;
282 int logical_block_size
;
284 if (!(mp
->mnt_flag
& MNT_RDONLY
))
288 * Disallow multiple mounts of the same device.
289 * Disallow mounting of a device that is currently in use
290 * Flush out any old buffers remaining from a previous use.
292 if ((error
= vfs_mountedon(devvp
)))
294 if (count_udev(devvp
->v_umajor
, devvp
->v_uminor
) > 0)
296 if ((error
= vinvalbuf(devvp
, V_SAVE
, 0, 0)))
299 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
300 error
= VOP_OPEN(devvp
, FREAD
, FSCRED
, NULL
);
305 if (dev
->si_iosize_max
!= 0)
306 mp
->mnt_iosize_max
= dev
->si_iosize_max
;
307 if (mp
->mnt_iosize_max
> MAXPHYS
)
308 mp
->mnt_iosize_max
= MAXPHYS
;
312 /* This is the "logical sector size". The standard says this
313 * should be 2048 or the physical sector size on the device,
314 * whichever is greater. For now, we'll just use a constant.
316 iso_bsize
= ISO_DEFAULT_BLOCK_SIZE
;
319 for (iso_blknum
= 16 + argp
->ssector
;
320 iso_blknum
< 100 + argp
->ssector
;
322 if ((error
= bread(devvp
, (off_t
)iso_blknum
* iso_bsize
,
323 iso_bsize
, &bp
)) != 0)
326 vdp
= (struct iso_volume_descriptor
*)bp
->b_data
;
327 if (bcmp (vdp
->id
, ISO_STANDARD_ID
, sizeof vdp
->id
) != 0) {
328 if (bcmp (vdp
->id_sierra
, ISO_SIERRA_ID
,
329 sizeof vdp
->id
) != 0) {
335 switch (isonum_711 (high_sierra
? vdp
->type_sierra
: vdp
->type
)){
340 pri
= (struct iso_primary_descriptor
*)vdp
;
342 (struct iso_sierra_primary_descriptor
*)vdp
;
346 case ISO_VD_SUPPLEMENTARY
:
350 sup
= (struct iso_supplementary_descriptor
*)vdp
;
352 if (!(argp
->flags
& ISOFSMNT_NOJOLIET
)) {
353 if (bcmp(sup
->escape
, "%/@", 3) == 0)
355 if (bcmp(sup
->escape
, "%/C", 3) == 0)
357 if (bcmp(sup
->escape
, "%/E", 3) == 0)
360 if ((isonum_711 (sup
->flags
) & 1) &&
361 (argp
->flags
& ISOFSMNT_BROKENJOLIET
) == 0)
390 isonum_723 (high_sierra
?
391 pri_sierra
->logical_block_size
:
392 pri
->logical_block_size
);
394 if (logical_block_size
< DEV_BSIZE
|| logical_block_size
> MAXBSIZE
395 || (logical_block_size
& (logical_block_size
- 1)) != 0) {
400 rootp
= (struct iso_directory_record
*)
402 pri_sierra
->root_directory_record
:
403 pri
->root_directory_record
);
405 isomp
= kmalloc(sizeof *isomp
, M_ISOFSMNT
, M_WAITOK
| M_ZERO
);
406 isomp
->logical_block_size
= logical_block_size
;
407 isomp
->volume_space_size
=
408 isonum_733 (high_sierra
?
409 pri_sierra
->volume_space_size
:
410 pri
->volume_space_size
);
411 isomp
->joliet_level
= 0;
413 * Since an ISO9660 multi-session CD can also access previous
414 * sessions, we have to include them into the space consider-
415 * ations. This doesn't yield a very accurate number since
416 * parts of the old sessions might be inaccessible now, but we
417 * can't do much better. This is also important for the NFS
418 * filehandle validation.
420 isomp
->volume_space_size
+= argp
->ssector
;
421 bcopy (rootp
, isomp
->root
, sizeof isomp
->root
);
422 isomp
->root_extent
= isonum_733 (rootp
->extent
);
423 isomp
->root_size
= isonum_733 (rootp
->size
);
425 isomp
->im_bmask
= logical_block_size
- 1;
426 isomp
->im_bshift
= ffs(logical_block_size
) - 1;
428 pribp
->b_flags
|= B_AGE
;
432 mp
->mnt_data
= (qaddr_t
)isomp
;
433 mp
->mnt_stat
.f_fsid
.val
[0] = dev2udev(dev
);
434 mp
->mnt_stat
.f_fsid
.val
[1] = mp
->mnt_vfc
->vfc_typenum
;
435 mp
->mnt_maxsymlinklen
= 0;
436 mp
->mnt_flag
|= MNT_LOCAL
;
437 isomp
->im_mountp
= mp
;
439 isomp
->im_devvp
= devvp
;
441 dev
->si_mountpoint
= mp
;
443 /* Check the Rock Ridge Extention support */
444 if (!(argp
->flags
& ISOFSMNT_NORRIP
)) {
445 if ((error
= bread(isomp
->im_devvp
,
446 lblktooff(isomp
, isomp
->root_extent
+ isonum_711(rootp
->ext_attr_length
)),
447 isomp
->logical_block_size
, &bp
)) != 0)
450 rootp
= (struct iso_directory_record
*)bp
->b_data
;
452 if ((isomp
->rr_skip
= cd9660_rrip_offset(rootp
,isomp
)) < 0) {
453 argp
->flags
|= ISOFSMNT_NORRIP
;
455 argp
->flags
&= ~ISOFSMNT_GENS
;
459 * The contents are valid,
460 * but they will get reread as part of another vnode, so...
462 bp
->b_flags
|= B_AGE
;
466 isomp
->im_flags
= argp
->flags
& (ISOFSMNT_NORRIP
| ISOFSMNT_GENS
|
467 ISOFSMNT_EXTATT
| ISOFSMNT_NOJOLIET
);
470 /* this effectively ignores all the mount flags */
471 log(LOG_INFO
, "cd9660: High Sierra Format\n");
472 isomp
->iso_ftype
= ISO_FTYPE_HIGH_SIERRA
;
474 switch (isomp
->im_flags
&(ISOFSMNT_NORRIP
|ISOFSMNT_GENS
)) {
476 isomp
->iso_ftype
= ISO_FTYPE_DEFAULT
;
478 case ISOFSMNT_GENS
|ISOFSMNT_NORRIP
:
479 isomp
->iso_ftype
= ISO_FTYPE_9660
;
482 log(LOG_INFO
, "cd9660: RockRidge Extension\n");
483 isomp
->iso_ftype
= ISO_FTYPE_RRIP
;
488 /* Decide whether to use the Joliet descriptor */
490 if (isomp
->iso_ftype
!= ISO_FTYPE_RRIP
&& joliet_level
) {
491 log(LOG_INFO
, "cd9660: Joliet Extension (Level %d)\n", joliet_level
);
492 rootp
= (struct iso_directory_record
*)
493 sup
->root_directory_record
;
494 bcopy (rootp
, isomp
->root
, sizeof isomp
->root
);
495 isomp
->root_extent
= isonum_733 (rootp
->extent
);
496 isomp
->root_size
= isonum_733 (rootp
->size
);
497 isomp
->joliet_level
= joliet_level
;
498 supbp
->b_flags
|= B_AGE
;
506 vfs_add_vnodeops(mp
, &cd9660_vnode_vops
, &mp
->mnt_vn_norm_ops
);
507 vfs_add_vnodeops(mp
, &cd9660_spec_vops
, &mp
->mnt_vn_spec_ops
);
508 vfs_add_vnodeops(mp
, &cd9660_fifo_vops
, &mp
->mnt_vn_fifo_ops
);
512 dev
->si_mountpoint
= NULL
;
520 VOP_CLOSE(devvp
, FREAD
);
522 kfree((caddr_t
)isomp
, M_ISOFSMNT
);
523 mp
->mnt_data
= (qaddr_t
)0;
529 * unmount system call
532 cd9660_unmount(struct mount
*mp
, int mntflags
)
534 struct iso_mnt
*isomp
;
535 int error
, flags
= 0;
537 if (mntflags
& MNT_FORCE
)
544 if ((error
= vflush(mp
, 0, flags
)))
547 isomp
= VFSTOISOFS(mp
);
549 isomp
->im_devvp
->v_rdev
->si_mountpoint
= NULL
;
550 error
= VOP_CLOSE(isomp
->im_devvp
, FREAD
);
551 vrele(isomp
->im_devvp
);
552 kfree((caddr_t
)isomp
, M_ISOFSMNT
);
553 mp
->mnt_data
= (qaddr_t
)0;
554 mp
->mnt_flag
&= ~MNT_LOCAL
;
559 * Return root of a filesystem
562 cd9660_root(struct mount
*mp
, struct vnode
**vpp
)
564 struct iso_mnt
*imp
= VFSTOISOFS(mp
);
565 struct iso_directory_record
*dp
=
566 (struct iso_directory_record
*)imp
->root
;
567 ino_t ino
= isodirino(dp
, imp
);
570 * With RRIP we must use the `.' entry of the root directory.
571 * Simply tell vget, that it's a relocated directory.
573 return (cd9660_vget_internal(mp
, ino
, vpp
,
574 imp
->iso_ftype
== ISO_FTYPE_RRIP
, dp
));
578 * Get file system statistics.
581 cd9660_statfs(struct mount
*mp
, struct statfs
*sbp
, struct ucred
*cred
)
583 struct iso_mnt
*isomp
;
585 isomp
= VFSTOISOFS(mp
);
587 sbp
->f_bsize
= isomp
->logical_block_size
;
588 sbp
->f_iosize
= sbp
->f_bsize
; /* XXX */
589 sbp
->f_blocks
= isomp
->volume_space_size
;
590 sbp
->f_bfree
= 0; /* total free blocks */
591 sbp
->f_bavail
= 0; /* blocks free for non superuser */
592 sbp
->f_files
= 0; /* total files */
593 sbp
->f_ffree
= 0; /* free file nodes */
594 if (sbp
!= &mp
->mnt_stat
) {
595 sbp
->f_type
= mp
->mnt_vfc
->vfc_typenum
;
596 bcopy(mp
->mnt_stat
.f_mntfromname
, sbp
->f_mntfromname
, MNAMELEN
);
602 * File handle to vnode
604 * Have to be really careful about stale file handles:
605 * - check that the inode number is in range
606 * - call iget() to get the locked inode
607 * - check for an unallocated inode (i_mode == 0)
608 * - check that the generation number matches
620 cd9660_fhtovp(struct mount
*mp
, struct vnode
*rootvp
,
621 struct fid
*fhp
, struct vnode
**vpp
)
623 struct ifid
*ifhp
= (struct ifid
*)fhp
;
629 kprintf("fhtovp: ino %d, start %ld\n",
630 ifhp
->ifid_ino
, ifhp
->ifid_start
);
633 if ((error
= VFS_VGET(mp
, ifhp
->ifid_ino
, &nvp
)) != 0) {
638 if (ip
->inode
.iso_mode
== 0) {
648 cd9660_checkexp(struct mount
*mp
, struct sockaddr
*nam
, int *exflagsp
,
649 struct ucred
**credanonp
)
654 imp
= VFSTOISOFS(mp
);
657 * Get the export permission structure for this <mp, client> tuple.
659 np
= vfs_export_lookup(mp
, &imp
->im_export
, nam
);
663 *exflagsp
= np
->netc_exflags
;
664 *credanonp
= &np
->netc_anon
;
669 cd9660_vget(struct mount
*mp
, ino_t ino
, struct vnode
**vpp
)
674 * It would be nice if we didn't always set the `relocated' flag
675 * and force the extra read, but I don't want to think about fixing
678 return (cd9660_vget_internal(mp
, ino
, vpp
,
680 VFSTOISOFS(mp
)->iso_ftype
== ISO_FTYPE_RRIP
,
684 (struct iso_directory_record
*)0));
688 cd9660_vget_internal(struct mount
*mp
, ino_t ino
, struct vnode
**vpp
,
689 int relocated
, struct iso_directory_record
*isodir
)
698 imp
= VFSTOISOFS(mp
);
701 if ((*vpp
= cd9660_ihashget(dev
, ino
)) != NULLVP
)
704 /* Allocate a new vnode/iso_node. */
705 error
= getnewvnode(VT_ISOFS
, mp
, &vp
, 0, 0);
710 MALLOC(ip
, struct iso_node
*, sizeof(struct iso_node
), M_ISOFSNODE
,
717 * Insert it into the inode hash table and check for a collision.
718 * If a collision occurs, throw away the vnode and try again.
720 if (cd9660_ihashins(ip
) != 0) {
721 kprintf("debug: cd9660 ihashins collision, retrying\n");
723 kfree(ip
, M_ISOFSNODE
);
728 if (isodir
== NULL
) {
731 lbn
= lblkno(imp
, ino
);
732 if (lbn
>= imp
->volume_space_size
) {
734 kprintf("fhtovp: lbn exceed volume space %d\n", lbn
);
738 off
= blkoff(imp
, ino
);
739 if (off
+ ISO_DIRECTORY_RECORD_SIZE
> imp
->logical_block_size
) {
741 kprintf("fhtovp: crosses block boundary %d\n",
742 off
+ ISO_DIRECTORY_RECORD_SIZE
);
746 error
= bread(imp
->im_devvp
,
748 imp
->logical_block_size
, &bp
);
752 kprintf("fhtovp: bread error %d\n",error
);
755 isodir
= (struct iso_directory_record
*)(bp
->b_data
+ off
);
757 if (off
+ isonum_711(isodir
->length
) >
758 imp
->logical_block_size
) {
762 kprintf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
763 off
+isonum_711(isodir
->length
), off
,
764 isonum_711(isodir
->length
));
769 if (isonum_733(isodir
->extent
) +
770 isonum_711(isodir
->ext_attr_length
) != ifhp
->ifid_start
) {
773 kprintf("fhtovp: file start miss %d vs %d\n",
774 isonum_733(isodir
->extent
) + isonum_711(isodir
->ext_attr_length
),
783 ip
->i_devvp
= imp
->im_devvp
;
788 * On relocated directories we must
789 * read the `.' entry out of a dir.
791 ip
->iso_start
= ino
>> imp
->im_bshift
;
794 if ((error
= cd9660_devblkatoff(vp
, (off_t
)0, NULL
, &bp
)) != 0) {
798 isodir
= (struct iso_directory_record
*)bp
->b_data
;
801 ip
->iso_extent
= isonum_733(isodir
->extent
);
802 ip
->i_size
= isonum_733(isodir
->size
);
803 ip
->iso_start
= isonum_711(isodir
->ext_attr_length
) + ip
->iso_extent
;
806 * Setup time stamp, attribute
809 switch (imp
->iso_ftype
) {
810 default: /* ISO_FTYPE_9660 */
814 if ((imp
->im_flags
& ISOFSMNT_EXTATT
)
815 && (off
= isonum_711(isodir
->ext_attr_length
)))
816 cd9660_devblkatoff(vp
, (off_t
)-(off
<< imp
->im_bshift
), NULL
,
820 cd9660_defattr(isodir
, ip
, bp2
, ISO_FTYPE_9660
);
821 cd9660_deftstamp(isodir
, ip
, bp2
, ISO_FTYPE_9660
);
827 cd9660_rrip_analyze(isodir
, ip
, imp
);
835 * Initialize the associated vnode
837 vp
->v_type
= IFTOVT(ip
->inode
.iso_mode
);
839 switch (vp
->v_type
) {
841 vp
->v_ops
= &mp
->mnt_vn_fifo_ops
;
845 vp
->v_ops
= &mp
->mnt_vn_spec_ops
;
846 addaliasu(vp
, umajor(ip
->inode
.iso_rdev
),
847 uminor(ip
->inode
.iso_rdev
));
851 vinitvmio(vp
, ip
->i_size
);
857 if (ip
->iso_extent
== imp
->root_extent
)
861 * Return the locked and refd vp
868 * Vnode pointer to File handle
872 cd9660_vptofh(struct vnode
*vp
, struct fid
*fhp
)
874 struct iso_node
*ip
= VTOI(vp
);
877 ifhp
= (struct ifid
*)fhp
;
878 ifhp
->ifid_len
= sizeof(struct ifid
);
880 ifhp
->ifid_ino
= ip
->i_number
;
881 ifhp
->ifid_start
= ip
->iso_start
;
884 kprintf("vptofh: ino %d, start %ld\n",
885 ifhp
->ifid_ino
,ifhp
->ifid_start
);