1 /* $NetBSD: cd9660_vfsops.c,v 1.90 2015/03/28 19:24:05 maxv Exp $ */
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley
8 * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
9 * Support code is derived from software contributed to Berkeley
10 * by Atsushi Murai (amurai@spec.co.jp).
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * @(#)cd9660_vfsops.c 8.18 (Berkeley) 5/22/95
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: cd9660_vfsops.c,v 1.90 2015/03/28 19:24:05 maxv Exp $");
42 #if defined(_KERNEL_OPT)
43 #include "opt_compat_netbsd.h"
46 #include <sys/param.h>
47 #include <sys/sysctl.h>
48 #include <sys/systm.h>
49 #include <sys/namei.h>
51 #include <sys/kernel.h>
52 #include <sys/vnode.h>
53 #include <miscfs/genfs/genfs.h>
54 #include <miscfs/specfs/specdev.h>
55 #include <sys/mount.h>
58 #include <sys/disklabel.h>
59 #include <sys/device.h>
60 #include <sys/ioctl.h>
62 #include <sys/errno.h>
63 #include <sys/malloc.h>
67 #include <sys/dirent.h>
68 #include <sys/kauth.h>
69 #include <sys/module.h>
71 #include <fs/cd9660/iso.h>
72 #include <fs/cd9660/cd9660_extern.h>
73 #include <fs/cd9660/iso_rrip.h>
74 #include <fs/cd9660/cd9660_node.h>
75 #include <fs/cd9660/cd9660_mount.h>
77 MODULE(MODULE_CLASS_VFS
, cd9660
, NULL
);
79 MALLOC_JUSTDEFINE(M_ISOFSMNT
, "ISOFS mount", "ISOFS mount structure");
81 static struct sysctllog
*cd9660_sysctl_log
;
83 extern const struct vnodeopv_desc cd9660_vnodeop_opv_desc
;
84 extern const struct vnodeopv_desc cd9660_specop_opv_desc
;
85 extern const struct vnodeopv_desc cd9660_fifoop_opv_desc
;
87 const struct vnodeopv_desc
* const cd9660_vnodeopv_descs
[] = {
88 &cd9660_vnodeop_opv_desc
,
89 &cd9660_specop_opv_desc
,
90 &cd9660_fifoop_opv_desc
,
94 struct vfsops cd9660_vfsops
= {
95 .vfs_name
= MOUNT_CD9660
,
96 .vfs_min_mount_data
= sizeof (struct iso_args
),
97 .vfs_mount
= cd9660_mount
,
98 .vfs_start
= cd9660_start
,
99 .vfs_unmount
= cd9660_unmount
,
100 .vfs_root
= cd9660_root
,
101 .vfs_quotactl
= (void *)eopnotsupp
,
102 .vfs_statvfs
= cd9660_statvfs
,
103 .vfs_sync
= cd9660_sync
,
104 .vfs_vget
= cd9660_vget
,
105 .vfs_loadvnode
= cd9660_loadvnode
,
106 .vfs_fhtovp
= cd9660_fhtovp
,
107 .vfs_vptofh
= cd9660_vptofh
,
108 .vfs_init
= cd9660_init
,
109 .vfs_reinit
= cd9660_reinit
,
110 .vfs_done
= cd9660_done
,
111 .vfs_mountroot
= cd9660_mountroot
,
112 .vfs_snapshot
= (void *)eopnotsupp
,
113 .vfs_extattrctl
= vfs_stdextattrctl
,
114 .vfs_suspendctl
= (void *)eopnotsupp
,
115 .vfs_renamelock_enter
= genfs_renamelock_enter
,
116 .vfs_renamelock_exit
= genfs_renamelock_exit
,
117 .vfs_fsync
= (void *)eopnotsupp
,
118 .vfs_opv_descs
= cd9660_vnodeopv_descs
121 static const struct genfs_ops cd9660_genfsops
= {
122 .gop_size
= genfs_size
,
126 * Called by vfs_mountroot when iso is going to be mounted as root.
128 * Name is updated by mount(8) after booting.
130 static int iso_makemp(struct iso_mnt
*isomp
, struct buf
*bp
, int *ea_len
);
131 static int iso_mountfs(struct vnode
*devvp
, struct mount
*mp
,
132 struct lwp
*l
, struct iso_args
*argp
);
135 cd9660_modcmd(modcmd_t cmd
, void *arg
)
140 case MODULE_CMD_INIT
:
141 error
= vfs_attach(&cd9660_vfsops
);
144 sysctl_createv(&cd9660_sysctl_log
, 0, NULL
, NULL
,
145 CTLFLAG_PERMANENT
, CTLTYPE_NODE
, "cd9660",
146 SYSCTL_DESCR("ISO-9660 file system"),
148 CTL_VFS
, 14, CTL_EOL
);
149 sysctl_createv(&cd9660_sysctl_log
, 0, NULL
, NULL
,
150 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
,
151 CTLTYPE_INT
, "utf8_joliet",
152 SYSCTL_DESCR("Encode Joliet filenames to UTF-8"),
153 NULL
, 0, &cd9660_utf8_joliet
, 0,
154 CTL_VFS
, 14, CD9660_UTF8_JOLIET
, CTL_EOL
);
156 * XXX the "14" above could be dynamic, thereby eliminating
157 * one more instance of the "number to vfs" mapping problem,
158 * but "14" is the order as taken from sys/mount.h
161 case MODULE_CMD_FINI
:
162 error
= vfs_detach(&cd9660_vfsops
);
165 sysctl_teardown(&cd9660_sysctl_log
);
176 cd9660_mountroot(void)
179 struct lwp
*l
= curlwp
;
181 struct iso_args args
;
183 if (device_class(root_device
) != DV_DISK
)
186 if ((error
= vfs_rootmountalloc(MOUNT_CD9660
, "root_device", &mp
))
192 args
.flags
= ISOFSMNT_ROOT
;
193 if ((error
= iso_mountfs(rootvp
, mp
, l
, &args
)) != 0) {
194 vfs_unbusy(mp
, false, NULL
);
198 mountlist_append(mp
);
199 (void)cd9660_statvfs(mp
, &mp
->mnt_stat
);
200 vfs_unbusy(mp
, false, NULL
);
210 cd9660_mount(struct mount
*mp
, const char *path
, void *data
, size_t *data_len
)
212 struct lwp
*l
= curlwp
;
214 struct iso_args
*args
= data
;
216 struct iso_mnt
*imp
= VFSTOISOFS(mp
);
220 if (*data_len
< sizeof *args
)
223 if (mp
->mnt_flag
& MNT_GETARGS
) {
227 args
->flags
= imp
->im_flags
;
228 *data_len
= sizeof (*args
);
232 if ((mp
->mnt_flag
& MNT_RDONLY
) == 0)
235 if ((mp
->mnt_flag
& MNT_UPDATE
) && args
->fspec
== NULL
)
239 * Not an update, or updating the name: look up the name
240 * and verify that it refers to a sensible block device.
242 error
= namei_simple_user(args
->fspec
,
243 NSM_FOLLOW_NOEMULROOT
, &devvp
);
247 if (devvp
->v_type
!= VBLK
) {
251 if (bdevsw_lookup(devvp
->v_rdev
) == NULL
) {
256 * If mount by non-root, then verify that user has necessary
257 * permissions on the device.
259 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
260 error
= kauth_authorize_system(l
->l_cred
, KAUTH_SYSTEM_MOUNT
,
261 KAUTH_REQ_SYSTEM_MOUNT_DEVICE
, mp
, devvp
, KAUTH_ARG(VREAD
));
265 if ((mp
->mnt_flag
& MNT_UPDATE
) == 0) {
266 error
= VOP_OPEN(devvp
, FREAD
, FSCRED
);
270 error
= iso_mountfs(devvp
, mp
, l
, args
);
271 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
273 (void)VOP_CLOSE(devvp
, FREAD
, NOCRED
);
277 /* reference to devvp is donated through iso_mountfs */
279 if (devvp
!= imp
->im_devvp
&&
280 devvp
->v_rdev
!= imp
->im_devvp
->v_rdev
) {
281 error
= EINVAL
; /* needs translation */
287 return set_statvfs_info(path
, UIO_USERSPACE
, args
->fspec
, UIO_USERSPACE
,
288 mp
->mnt_op
->vfs_name
, mp
, l
);
297 * Make a mount point from a volume descriptor
300 iso_makemp(struct iso_mnt
*isomp
, struct buf
*bp
, int *ea_len
)
302 struct iso_primary_descriptor
*pri
;
303 int logical_block_size
;
304 struct iso_directory_record
*rootp
;
306 pri
= (struct iso_primary_descriptor
*)bp
->b_data
;
308 logical_block_size
= isonum_723 (pri
->logical_block_size
);
310 if (logical_block_size
< DEV_BSIZE
|| logical_block_size
> MAXBSIZE
311 || (logical_block_size
& (logical_block_size
- 1)) != 0)
314 rootp
= (struct iso_directory_record
*)pri
->root_directory_record
;
316 isomp
->logical_block_size
= logical_block_size
;
317 isomp
->volume_space_size
= isonum_733 (pri
->volume_space_size
);
318 memcpy(isomp
->root
, rootp
, sizeof(isomp
->root
));
319 isomp
->root_extent
= isonum_733 (rootp
->extent
);
320 isomp
->root_size
= isonum_733 (rootp
->size
);
321 isomp
->im_joliet_level
= 0;
323 isomp
->im_bmask
= logical_block_size
- 1;
324 isomp
->im_bshift
= 0;
325 while ((1 << isomp
->im_bshift
) < isomp
->logical_block_size
)
329 *ea_len
= isonum_711(rootp
->ext_attr_length
);
335 * Common code for mount and mountroot
338 iso_mountfs(struct vnode
*devvp
, struct mount
*mp
, struct lwp
*l
,
339 struct iso_args
*argp
)
341 struct iso_mnt
*isomp
= (struct iso_mnt
*)0;
342 struct buf
*bp
= NULL
, *pribp
= NULL
, *supbp
= NULL
;
343 dev_t dev
= devvp
->v_rdev
;
345 int ronly
= (mp
->mnt_flag
& MNT_RDONLY
) != 0;
349 struct iso_volume_descriptor
*vdp
;
350 struct iso_supplementary_descriptor
*sup
;
353 struct disklabel label
;
358 /* Flush out any old buffers remaining from a previous use. */
359 if ((error
= vinvalbuf(devvp
, V_SAVE
, l
->l_cred
, l
, 0, 0)) != 0)
362 /* This is the "logical sector size". The standard says this
363 * should be 2048 or the physical sector size on the device,
364 * whichever is greater. For now, we'll just use a constant.
366 iso_bsize
= ISO_DEFAULT_BLOCK_SIZE
;
368 error
= VOP_IOCTL(devvp
, DIOCGDINFO
, &label
, FREAD
, FSCRED
);
370 /* XXX more sanity checks? */
371 sess
= label
.d_partitions
[DISKPART(dev
)].p_cdsession
;
373 /* fallback to old method */
374 error
= VOP_IOCTL(devvp
, CDIOREADMSADDR
, &sess
, 0, FSCRED
);
376 sess
= 0; /* never mind */
379 printf("isofs: session offset (part %"PRId32
") %d\n", DISKPART(dev
), sess
);
382 for (iso_blknum
= 16; iso_blknum
< 100; iso_blknum
++) {
383 if ((error
= bread(devvp
, (iso_blknum
+sess
) * btodb(iso_bsize
),
384 iso_bsize
, 0, &bp
)) != 0)
387 vdp
= (struct iso_volume_descriptor
*)bp
->b_data
;
388 if (memcmp(vdp
->id
, ISO_STANDARD_ID
, sizeof(vdp
->id
)) != 0) {
393 switch (isonum_711(vdp
->type
)) {
401 case ISO_VD_SUPPLEMENTARY
:
412 if (isonum_711 (vdp
->type
) == ISO_VD_END
) {
429 isomp
= malloc(sizeof *isomp
, M_ISOFSMNT
, M_WAITOK
);
430 memset(isomp
, 0, sizeof *isomp
);
431 if (iso_makemp(isomp
, pribp
, &ext_attr_length
) == -1) {
436 isomp
->volume_space_size
+= sess
;
438 brelse(pribp
, BC_AGE
);
441 mp
->mnt_data
= isomp
;
442 mp
->mnt_stat
.f_fsidx
.__fsid_val
[0] = (long)dev
;
443 mp
->mnt_stat
.f_fsidx
.__fsid_val
[1] = makefstype(MOUNT_CD9660
);
444 mp
->mnt_stat
.f_fsid
= mp
->mnt_stat
.f_fsidx
.__fsid_val
[0];
445 mp
->mnt_stat
.f_namemax
= ISO_MAXNAMLEN
;
446 mp
->mnt_flag
|= MNT_LOCAL
;
447 mp
->mnt_iflag
|= IMNT_MPSAFE
;
448 mp
->mnt_dev_bshift
= iso_bsize
;
449 mp
->mnt_fs_bshift
= isomp
->im_bshift
;
450 isomp
->im_mountp
= mp
;
452 isomp
->im_devvp
= devvp
;
454 /* Check the Rock Ridge Extension support */
455 if (!(argp
->flags
& ISOFSMNT_NORRIP
)) {
456 struct iso_directory_record
*rootp
;
458 if ((error
= bread(isomp
->im_devvp
,
459 (isomp
->root_extent
+ ext_attr_length
) <<
460 (isomp
->im_bshift
- DEV_BSHIFT
),
461 isomp
->logical_block_size
,
465 rootp
= (struct iso_directory_record
*)bp
->b_data
;
467 if ((isomp
->rr_skip
= cd9660_rrip_offset(rootp
,isomp
)) < 0) {
468 argp
->flags
|= ISOFSMNT_NORRIP
;
470 argp
->flags
&= ~ISOFSMNT_GENS
;
474 * The contents are valid,
475 * but they will get reread as part of another vnode, so...
480 isomp
->im_flags
= argp
->flags
& (ISOFSMNT_NORRIP
| ISOFSMNT_GENS
|
481 ISOFSMNT_EXTATT
| ISOFSMNT_NOJOLIET
| ISOFSMNT_RRCASEINS
);
483 if (isomp
->im_flags
& ISOFSMNT_GENS
)
484 isomp
->iso_ftype
= ISO_FTYPE_9660
;
485 else if (isomp
->im_flags
& ISOFSMNT_NORRIP
) {
486 isomp
->iso_ftype
= ISO_FTYPE_DEFAULT
;
487 if (argp
->flags
& ISOFSMNT_NOCASETRANS
)
488 isomp
->im_flags
|= ISOFSMNT_NOCASETRANS
;
490 isomp
->iso_ftype
= ISO_FTYPE_RRIP
;
492 /* Check the Joliet Extension support */
493 if ((argp
->flags
& ISOFSMNT_NORRIP
) != 0 &&
494 (argp
->flags
& ISOFSMNT_NOJOLIET
) == 0 &&
497 sup
= (struct iso_supplementary_descriptor
*)supbp
->b_data
;
499 if ((isonum_711(sup
->flags
) & 1) == 0) {
500 if (memcmp(sup
->escape
, "%/@", 3) == 0)
502 if (memcmp(sup
->escape
, "%/C", 3) == 0)
504 if (memcmp(sup
->escape
, "%/E", 3) == 0)
507 if (joliet_level
!= 0) {
508 if (iso_makemp(isomp
, supbp
, NULL
) == -1) {
512 isomp
->im_joliet_level
= joliet_level
;
521 spec_node_setmountedfs(devvp
, mp
);
532 free(isomp
, M_ISOFSMNT
);
539 * Make a filesystem operational.
540 * Nothing to do at the moment.
544 cd9660_start(struct mount
*mp
, int flags
)
550 * unmount system call
553 cd9660_unmount(struct mount
*mp
, int mntflags
)
555 struct iso_mnt
*isomp
;
556 int error
, flags
= 0;
558 if (mntflags
& MNT_FORCE
)
560 if ((error
= vflush(mp
, NULLVP
, flags
)) != 0)
563 isomp
= VFSTOISOFS(mp
);
565 if (isomp
->im_devvp
->v_type
!= VBAD
)
566 spec_node_setmountedfs(isomp
->im_devvp
, NULL
);
568 vn_lock(isomp
->im_devvp
, LK_EXCLUSIVE
| LK_RETRY
);
569 error
= VOP_CLOSE(isomp
->im_devvp
, FREAD
, NOCRED
);
570 vput(isomp
->im_devvp
);
571 free(isomp
, M_ISOFSMNT
);
573 mp
->mnt_flag
&= ~MNT_LOCAL
;
578 * Return root of a filesystem
581 cd9660_root(struct mount
*mp
, struct vnode
**vpp
)
583 struct iso_mnt
*imp
= VFSTOISOFS(mp
);
584 struct iso_directory_record
*dp
=
585 (struct iso_directory_record
*)imp
->root
;
586 ino_t ino
= isodirino(dp
, imp
);
588 return cd9660_vget(mp
, ino
, vpp
);
592 * Get file system statistics.
595 cd9660_statvfs(struct mount
*mp
, struct statvfs
*sbp
)
597 struct iso_mnt
*isomp
;
599 isomp
= VFSTOISOFS(mp
);
601 sbp
->f_bsize
= isomp
->logical_block_size
;
602 sbp
->f_frsize
= sbp
->f_bsize
;
603 sbp
->f_iosize
= sbp
->f_bsize
; /* XXX */
604 sbp
->f_blocks
= isomp
->volume_space_size
;
605 sbp
->f_bfree
= 0; /* total free blocks */
606 sbp
->f_bavail
= 0; /* blocks free for non superuser */
607 sbp
->f_bresvd
= 0; /* total reserved blocks */
608 sbp
->f_files
= 0; /* total files */
609 sbp
->f_ffree
= 0; /* free file nodes */
610 sbp
->f_favail
= 0; /* free file nodes for non superuser */
611 sbp
->f_fresvd
= 0; /* reserved file nodes */
612 copy_statvfs_info(sbp
, mp
);
613 /* Use the first spare for flags: */
614 sbp
->f_spare
[0] = isomp
->im_flags
;
620 cd9660_sync(struct mount
*mp
, int waitfor
, kauth_cred_t cred
)
626 * File handle to vnode
628 * Have to be really careful about stale file handles:
629 * - check that the inode number is in range
630 * - call iget() to get the locked inode
631 * - check for an unallocated inode (i_mode == 0)
632 * - check that the generation number matches
646 cd9660_fhtovp(struct mount
*mp
, struct fid
*fhp
, struct vnode
**vpp
)
653 if (fhp
->fid_len
!= sizeof(ifh
))
656 memcpy(&ifh
, fhp
, sizeof(ifh
));
658 printf("fhtovp: ino %"PRIu64
", start %lu\n",
659 ifh
.ifid_ino
, ifh
.ifid_start
);
662 if ((error
= VFS_VGET(mp
, ifh
.ifid_ino
, &nvp
)) != 0) {
667 if (ip
->inode
.iso_mode
== 0) {
677 cd9660_vget(struct mount
*mp
, ino_t ino
, struct vnode
**vpp
)
681 error
= vcache_get(mp
, &ino
, sizeof(ino
), vpp
);
684 error
= vn_lock(*vpp
, LK_EXCLUSIVE
);
694 cd9660_loadvnode(struct mount
*mp
, struct vnode
*vp
,
695 const void *key
, size_t key_len
, const void **new_key
)
699 struct iso_directory_record
*isodir
;
706 KASSERT(key_len
== sizeof(ino
));
707 memcpy(&ino
, key
, key_len
);
708 imp
= VFSTOISOFS(mp
);
711 ip
= pool_get(&cd9660_node_pool
, PR_WAITOK
);
713 memset(ip
, 0, sizeof(struct iso_node
));
718 ip
->i_devvp
= imp
->im_devvp
;
720 lbn
= cd9660_lblkno(imp
, ino
);
721 if (lbn
>= imp
->volume_space_size
) {
722 pool_put(&cd9660_node_pool
, ip
);
723 printf("fhtovp: lbn exceed volume space %d\n", lbn
);
727 off
= cd9660_blkoff(imp
, ino
);
728 if (off
+ ISO_DIRECTORY_RECORD_SIZE
> imp
->logical_block_size
) {
729 pool_put(&cd9660_node_pool
, ip
);
730 printf("fhtovp: crosses block boundary %d\n",
731 off
+ ISO_DIRECTORY_RECORD_SIZE
);
735 error
= bread(imp
->im_devvp
,
736 lbn
<< (imp
->im_bshift
- DEV_BSHIFT
),
737 imp
->logical_block_size
, 0, &bp
);
739 pool_put(&cd9660_node_pool
, ip
);
740 printf("fhtovp: bread error %d\n",error
);
743 isodir
= (struct iso_directory_record
*)((char *)bp
->b_data
+ off
);
745 if (off
+ isonum_711(isodir
->length
) > imp
->logical_block_size
) {
746 pool_put(&cd9660_node_pool
, ip
);
748 printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
749 off
+isonum_711(isodir
->length
), off
,
750 isonum_711(isodir
->length
));
755 if (isonum_733(isodir
->extent
) +
756 isonum_711(isodir
->ext_attr_length
) != ifhp
->ifid_start
) {
757 pool_put(&cd9660_node_pool
, ip
);
760 printf("fhtovp: file start miss %d vs %d\n",
761 isonum_733(isodir
->extent
) + isonum_711(isodir
->ext_attr_length
),
767 ip
->iso_extent
= isonum_733(isodir
->extent
);
768 ip
->i_size
= isonum_733(isodir
->size
);
769 ip
->iso_start
= isonum_711(isodir
->ext_attr_length
) + ip
->iso_extent
;
771 vp
->v_tag
= VT_ISOFS
;
772 vp
->v_op
= cd9660_vnodeop_p
;
774 genfs_node_init(vp
, &cd9660_genfsops
);
777 * Setup time stamp, attribute
779 switch (imp
->iso_ftype
) {
780 default: /* ISO_FTYPE_9660 */
783 if ((imp
->im_flags
& ISOFSMNT_EXTATT
)
784 && (off
= isonum_711(isodir
->ext_attr_length
)))
785 cd9660_blkatoff(vp
, (off_t
)-(off
<< imp
->im_bshift
),
789 cd9660_defattr(isodir
, ip
, bp2
);
790 cd9660_deftstamp(isodir
, ip
, bp2
);
796 cd9660_rrip_analyze(isodir
, ip
, imp
);
803 * Initialize the associated vnode
805 switch (vp
->v_type
= IFTOVT(ip
->inode
.iso_mode
)) {
807 vp
->v_op
= cd9660_fifoop_p
;
812 * if device, look at device number table for translation
814 vp
->v_op
= cd9660_specop_p
;
815 spec_node_init(vp
, ip
->inode
.iso_rdev
);
824 uvm_vnp_setsize(vp
, ip
->i_size
);
828 if (vp
->v_type
!= VREG
)
829 uvm_vnp_setsize(vp
, 0);
831 if (ip
->iso_extent
== imp
->root_extent
)
832 vp
->v_vflag
|= VV_ROOT
;
835 * XXX need generation number?
838 *new_key
= &ip
->i_number
;
843 * Vnode pointer to File handle
847 cd9660_vptofh(struct vnode
*vp
, struct fid
*fhp
, size_t *fh_size
)
849 struct iso_node
*ip
= VTOI(vp
);
852 if (*fh_size
< sizeof(struct ifid
)) {
853 *fh_size
= sizeof(struct ifid
);
856 *fh_size
= sizeof(struct ifid
);
858 memset(&ifh
, 0, sizeof(ifh
));
859 ifh
.ifid_len
= sizeof(struct ifid
);
860 ifh
.ifid_ino
= ip
->i_number
;
862 ifh
.ifid_start
= ip
->iso_start
;
864 memcpy(fhp
, &ifh
, sizeof(ifh
));
867 printf("vptofh: ino %"PRIu64
", start %lu\n",
868 ifh
.ifid_ino
,ifh
.ifid_start
);