1*4f12c8abSsemarie /* $OpenBSD: cd9660_node.c,v 1.38 2021/10/19 06:11:45 semarie Exp $ */
2053e05a2Sniklas /* $NetBSD: cd9660_node.c,v 1.17 1997/05/05 07:13:57 mycroft Exp $ */
3df930be7Sderaadt
4df930be7Sderaadt /*-
5df930be7Sderaadt * Copyright (c) 1982, 1986, 1989, 1994
6df930be7Sderaadt * The Regents of the University of California. All rights reserved.
7df930be7Sderaadt *
8df930be7Sderaadt * This code is derived from software contributed to Berkeley
9df930be7Sderaadt * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
10df930be7Sderaadt * Support code is derived from software contributed to Berkeley
11df930be7Sderaadt * by Atsushi Murai (amurai@spec.co.jp).
12df930be7Sderaadt *
13df930be7Sderaadt * Redistribution and use in source and binary forms, with or without
14df930be7Sderaadt * modification, are permitted provided that the following conditions
15df930be7Sderaadt * are met:
16df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright
17df930be7Sderaadt * notice, this list of conditions and the following disclaimer.
18df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright
19df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the
20df930be7Sderaadt * documentation and/or other materials provided with the distribution.
2129295d1cSmillert * 3. Neither the name of the University nor the names of its contributors
22df930be7Sderaadt * may be used to endorse or promote products derived from this software
23df930be7Sderaadt * without specific prior written permission.
24df930be7Sderaadt *
25df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35df930be7Sderaadt * SUCH DAMAGE.
36df930be7Sderaadt *
37df930be7Sderaadt * @(#)cd9660_node.c 8.5 (Berkeley) 12/5/94
38df930be7Sderaadt */
39df930be7Sderaadt
40df930be7Sderaadt #include <sys/param.h>
41df930be7Sderaadt #include <sys/systm.h>
42df930be7Sderaadt #include <sys/mount.h>
43df930be7Sderaadt #include <sys/buf.h>
44df930be7Sderaadt #include <sys/vnode.h>
45fde894e5Stedu #include <sys/lock.h>
469d71829cSniklas #include <sys/namei.h>
47df930be7Sderaadt #include <sys/kernel.h>
48df930be7Sderaadt #include <sys/malloc.h>
49df930be7Sderaadt #include <sys/stat.h>
50df930be7Sderaadt
519dc9bb81Sdlg #include <crypto/siphash.h>
529dc9bb81Sdlg
53df930be7Sderaadt #include <isofs/cd9660/iso.h>
54053e05a2Sniklas #include <isofs/cd9660/cd9660_extern.h>
55df930be7Sderaadt #include <isofs/cd9660/cd9660_node.h>
56df930be7Sderaadt
57df930be7Sderaadt /*
58df930be7Sderaadt * Structures associated with iso_node caching.
59df930be7Sderaadt */
609dc9bb81Sdlg u_int cd9660_isohash(dev_t, cdino_t);
619dc9bb81Sdlg
62df930be7Sderaadt struct iso_node **isohashtbl;
63df930be7Sderaadt u_long isohash;
649dc9bb81Sdlg SIPHASH_KEY isohashkey;
659dc9bb81Sdlg #define INOHASH(device, inum) cd9660_isohash((device), (inum))
66df930be7Sderaadt
6782be8208Sjason extern int prtactive; /* 1 => print out reclaim of active vnodes */
68df930be7Sderaadt
69c4071fd1Smillert static u_int cd9660_chars2ui(u_char *, int);
70053e05a2Sniklas
71df930be7Sderaadt /*
72df930be7Sderaadt * Initialize hash links for inodes and dnodes.
73df930be7Sderaadt */
7407feb63cScsapuntz int
cd9660_init(struct vfsconf * vfsp)751bf87d88Sjsg cd9660_init(struct vfsconf *vfsp)
76df930be7Sderaadt {
77df930be7Sderaadt
786dfb9ddeStedu isohashtbl = hashinit(initialvnodes, M_ISOFSMNT, M_WAITOK, &isohash);
799dc9bb81Sdlg arc4random_buf(&isohashkey, sizeof(isohashkey));
8007feb63cScsapuntz return (0);
81df930be7Sderaadt }
82df930be7Sderaadt
839dc9bb81Sdlg u_int
cd9660_isohash(dev_t device,cdino_t inum)849dc9bb81Sdlg cd9660_isohash(dev_t device, cdino_t inum)
859dc9bb81Sdlg {
869dc9bb81Sdlg SIPHASH_CTX ctx;
879dc9bb81Sdlg
889dc9bb81Sdlg SipHash24_Init(&ctx, &isohashkey);
899dc9bb81Sdlg SipHash24_Update(&ctx, &device, sizeof(device));
909dc9bb81Sdlg SipHash24_Update(&ctx, &inum, sizeof(inum));
919dc9bb81Sdlg return (SipHash24_End(&ctx) & isohash);
929dc9bb81Sdlg }
939dc9bb81Sdlg
94df930be7Sderaadt /*
95df930be7Sderaadt * Use the device/inum pair to find the incore inode, and return a pointer
96df930be7Sderaadt * to it. If it is in core, but locked, wait for it.
97df930be7Sderaadt */
98df930be7Sderaadt struct vnode *
cd9660_ihashget(dev_t dev,cdino_t inum)991bf87d88Sjsg cd9660_ihashget(dev_t dev, cdino_t inum)
100df930be7Sderaadt {
10107feb63cScsapuntz struct iso_node *ip;
102df930be7Sderaadt struct vnode *vp;
103df930be7Sderaadt
10407feb63cScsapuntz loop:
1055deff29eSoga /* XXX locking lock hash list? */
10607feb63cScsapuntz for (ip = isohashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) {
10707feb63cScsapuntz if (inum == ip->i_number && dev == ip->i_dev) {
108f6d35f95Sderaadt vp = ITOV(ip);
1095deff29eSoga /* XXX locking unlock hash list? */
11008107a0bSvisa if (vget(vp, LK_EXCLUSIVE))
11107feb63cScsapuntz goto loop;
112f6d35f95Sderaadt return (vp);
113f6d35f95Sderaadt }
114f6d35f95Sderaadt }
1155deff29eSoga /* XXX locking unlock hash list? */
11607feb63cScsapuntz return (NULL);
117df930be7Sderaadt }
118df930be7Sderaadt
119df930be7Sderaadt /*
120df930be7Sderaadt * Insert the inode into the hash table, and return it locked.
121df930be7Sderaadt */
122d91bc836Scsapuntz int
cd9660_ihashins(struct iso_node * ip)1231bf87d88Sjsg cd9660_ihashins(struct iso_node *ip)
124df930be7Sderaadt {
125df930be7Sderaadt struct iso_node **ipp, *iq;
126df930be7Sderaadt
1275deff29eSoga /* XXX locking lock hash list? */
128df930be7Sderaadt ipp = &isohashtbl[INOHASH(ip->i_dev, ip->i_number)];
129d91bc836Scsapuntz
130d91bc836Scsapuntz for (iq = *ipp; iq; iq = iq->i_next) {
131d91bc836Scsapuntz if (iq->i_dev == ip->i_dev &&
132d91bc836Scsapuntz iq->i_number == ip->i_number)
133d91bc836Scsapuntz return (EEXIST);
134d91bc836Scsapuntz }
135d91bc836Scsapuntz
1369d71829cSniklas if ((iq = *ipp) != NULL)
137df930be7Sderaadt iq->i_prev = &ip->i_next;
138df930be7Sderaadt ip->i_next = iq;
139df930be7Sderaadt ip->i_prev = ipp;
140df930be7Sderaadt *ipp = ip;
1415deff29eSoga /* XXX locking unlock hash list? */
14207feb63cScsapuntz
143*4f12c8abSsemarie VOP_LOCK(ITOV(ip), LK_EXCLUSIVE);
1442752fedbSpedro
145d91bc836Scsapuntz return (0);
146df930be7Sderaadt }
147df930be7Sderaadt
148df930be7Sderaadt /*
149df930be7Sderaadt * Remove the inode from the hash table.
150df930be7Sderaadt */
151df930be7Sderaadt void
cd9660_ihashrem(struct iso_node * ip)1521bf87d88Sjsg cd9660_ihashrem(struct iso_node *ip)
153df930be7Sderaadt {
154b2acc587Sjsg struct iso_node *iq;
155df930be7Sderaadt
156d91bc836Scsapuntz if (ip->i_prev == NULL)
157d91bc836Scsapuntz return;
158d91bc836Scsapuntz
1595deff29eSoga /* XXX locking lock hash list? */
1609d71829cSniklas if ((iq = ip->i_next) != NULL)
161df930be7Sderaadt iq->i_prev = ip->i_prev;
162df930be7Sderaadt *ip->i_prev = iq;
163df930be7Sderaadt #ifdef DIAGNOSTIC
164df930be7Sderaadt ip->i_next = NULL;
165df930be7Sderaadt ip->i_prev = NULL;
166df930be7Sderaadt #endif
1675deff29eSoga /* XXX locking unlock hash list? */
168df930be7Sderaadt }
169df930be7Sderaadt
170df930be7Sderaadt /*
171df930be7Sderaadt * Last reference to an inode, write the inode out and if necessary,
172df930be7Sderaadt * truncate and deallocate the file.
173df930be7Sderaadt */
174df930be7Sderaadt int
cd9660_inactive(void * v)1751bf87d88Sjsg cd9660_inactive(void *v)
1769d71829cSniklas {
17799bc9d31Sderaadt struct vop_inactive_args *ap = v;
178df930be7Sderaadt struct vnode *vp = ap->a_vp;
179b2acc587Sjsg struct iso_node *ip = VTOI(vp);
180df930be7Sderaadt int error = 0;
181df930be7Sderaadt
1824df17c52Spedro #ifdef DIAGNOSTIC
183df930be7Sderaadt if (prtactive && vp->v_usecount != 0)
184df930be7Sderaadt vprint("cd9660_inactive: pushing active", vp);
1854df17c52Spedro #endif
186df930be7Sderaadt
187df930be7Sderaadt ip->i_flag = 0;
18836bb23f1Svisa VOP_UNLOCK(vp);
189df930be7Sderaadt /*
190df930be7Sderaadt * If we are done with the inode, reclaim it
191df930be7Sderaadt * so that it can be reused immediately.
192df930be7Sderaadt */
19307feb63cScsapuntz if (ip->inode.iso_mode == 0)
194db7aa982Smpi vrecycle(vp, ap->a_p);
19507feb63cScsapuntz
196053e05a2Sniklas return (error);
197df930be7Sderaadt }
198df930be7Sderaadt
199df930be7Sderaadt /*
200df930be7Sderaadt * Reclaim an inode so that it can be used for other purposes.
201df930be7Sderaadt */
202df930be7Sderaadt int
cd9660_reclaim(void * v)2031bf87d88Sjsg cd9660_reclaim(void *v)
2049d71829cSniklas {
20599bc9d31Sderaadt struct vop_reclaim_args *ap = v;
206b2acc587Sjsg struct vnode *vp = ap->a_vp;
207b2acc587Sjsg struct iso_node *ip = VTOI(vp);
208df930be7Sderaadt
2094df17c52Spedro #ifdef DIAGNOSTIC
210df930be7Sderaadt if (prtactive && vp->v_usecount != 0)
211df930be7Sderaadt vprint("cd9660_reclaim: pushing active", vp);
2124df17c52Spedro #endif
2134df17c52Spedro
214df930be7Sderaadt /*
215df930be7Sderaadt * Remove the inode from its hash chain.
216df930be7Sderaadt */
217df930be7Sderaadt cd9660_ihashrem(ip);
218df930be7Sderaadt /*
219df930be7Sderaadt * Purge old data structures associated with the inode.
220df930be7Sderaadt */
221df930be7Sderaadt cache_purge(vp);
222df930be7Sderaadt if (ip->i_devvp) {
223df930be7Sderaadt vrele(ip->i_devvp);
224df930be7Sderaadt ip->i_devvp = 0;
225df930be7Sderaadt }
2260e5ae731Stedu free(vp->v_data, M_ISOFSNODE, 0);
227df930be7Sderaadt vp->v_data = NULL;
228df930be7Sderaadt return (0);
229df930be7Sderaadt }
230df930be7Sderaadt
231df930be7Sderaadt /*
232df930be7Sderaadt * File attributes
233df930be7Sderaadt */
234df930be7Sderaadt void
cd9660_defattr(struct iso_directory_record * isodir,struct iso_node * inop,struct buf * bp)2351bf87d88Sjsg cd9660_defattr(struct iso_directory_record *isodir, struct iso_node *inop,
2361bf87d88Sjsg struct buf *bp)
237df930be7Sderaadt {
238df930be7Sderaadt struct buf *bp2 = NULL;
239df930be7Sderaadt struct iso_mnt *imp;
240df930be7Sderaadt struct iso_extended_attributes *ap = NULL;
241df930be7Sderaadt int off;
242df930be7Sderaadt
243df930be7Sderaadt if (isonum_711(isodir->flags)&2) {
244df930be7Sderaadt inop->inode.iso_mode = S_IFDIR;
245df930be7Sderaadt /*
246df930be7Sderaadt * If we return 2, fts() will assume there are no subdirectories
247df930be7Sderaadt * (just links for the path and .), so instead we return 1.
248df930be7Sderaadt */
249df930be7Sderaadt inop->inode.iso_links = 1;
250df930be7Sderaadt } else {
251df930be7Sderaadt inop->inode.iso_mode = S_IFREG;
252df930be7Sderaadt inop->inode.iso_links = 1;
253df930be7Sderaadt }
254df930be7Sderaadt if (!bp
255df930be7Sderaadt && ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT)
256df930be7Sderaadt && (off = isonum_711(isodir->ext_attr_length))) {
257574066a2Scsapuntz cd9660_bufatoff(inop, (off_t)-(off << imp->im_bshift), NULL,
258df930be7Sderaadt &bp2);
259df930be7Sderaadt bp = bp2;
260df930be7Sderaadt }
261df930be7Sderaadt if (bp) {
262df930be7Sderaadt ap = (struct iso_extended_attributes *)bp->b_data;
263df930be7Sderaadt
264df930be7Sderaadt if (isonum_711(ap->version) == 1) {
265df930be7Sderaadt if (!(ap->perm[1]&0x10))
26693de0522Smillert inop->inode.iso_mode |= S_IRUSR;
26793de0522Smillert if (!(ap->perm[1]&0x40))
26893de0522Smillert inop->inode.iso_mode |= S_IXUSR;
26993de0522Smillert if (!(ap->perm[0]&0x01))
27093de0522Smillert inop->inode.iso_mode |= S_IRGRP;
27193de0522Smillert if (!(ap->perm[0]&0x04))
27293de0522Smillert inop->inode.iso_mode |= S_IXGRP;
27393de0522Smillert if (!(ap->perm[0]&0x10))
27493de0522Smillert inop->inode.iso_mode |= S_IROTH;
27593de0522Smillert if (!(ap->perm[0]&0x40))
27693de0522Smillert inop->inode.iso_mode |= S_IXOTH;
277df930be7Sderaadt inop->inode.iso_uid = isonum_723(ap->owner); /* what about 0? */
278df930be7Sderaadt inop->inode.iso_gid = isonum_723(ap->group); /* what about 0? */
279df930be7Sderaadt } else
280df930be7Sderaadt ap = NULL;
281df930be7Sderaadt }
282df930be7Sderaadt if (!ap) {
28393de0522Smillert inop->inode.iso_mode |=
28493de0522Smillert S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
285df930be7Sderaadt inop->inode.iso_uid = (uid_t)0;
286df930be7Sderaadt inop->inode.iso_gid = (gid_t)0;
287df930be7Sderaadt }
288df930be7Sderaadt if (bp2)
289df930be7Sderaadt brelse(bp2);
290df930be7Sderaadt }
291df930be7Sderaadt
292df930be7Sderaadt /*
293df930be7Sderaadt * Time stamps
294df930be7Sderaadt */
295df930be7Sderaadt void
cd9660_deftstamp(struct iso_directory_record * isodir,struct iso_node * inop,struct buf * bp)2961bf87d88Sjsg cd9660_deftstamp(struct iso_directory_record *isodir, struct iso_node *inop,
2971bf87d88Sjsg struct buf *bp)
298df930be7Sderaadt {
299df930be7Sderaadt struct buf *bp2 = NULL;
300df930be7Sderaadt struct iso_mnt *imp;
301df930be7Sderaadt struct iso_extended_attributes *ap = NULL;
302df930be7Sderaadt int off;
303df930be7Sderaadt
304df930be7Sderaadt if (!bp
305df930be7Sderaadt && ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT)
306df930be7Sderaadt && (off = isonum_711(isodir->ext_attr_length))) {
307574066a2Scsapuntz cd9660_bufatoff(inop, (off_t)-(off << imp->im_bshift), NULL,
308df930be7Sderaadt &bp2);
309df930be7Sderaadt bp = bp2;
310df930be7Sderaadt }
311df930be7Sderaadt if (bp) {
312df930be7Sderaadt ap = (struct iso_extended_attributes *)bp->b_data;
313df930be7Sderaadt
314df930be7Sderaadt if (isonum_711(ap->version) == 1) {
315df930be7Sderaadt if (!cd9660_tstamp_conv17(ap->ftime,&inop->inode.iso_atime))
316df930be7Sderaadt cd9660_tstamp_conv17(ap->ctime,&inop->inode.iso_atime);
317df930be7Sderaadt if (!cd9660_tstamp_conv17(ap->ctime,&inop->inode.iso_ctime))
318df930be7Sderaadt inop->inode.iso_ctime = inop->inode.iso_atime;
319df930be7Sderaadt if (!cd9660_tstamp_conv17(ap->mtime,&inop->inode.iso_mtime))
320df930be7Sderaadt inop->inode.iso_mtime = inop->inode.iso_ctime;
321df930be7Sderaadt } else
322df930be7Sderaadt ap = NULL;
323df930be7Sderaadt }
324df930be7Sderaadt if (!ap) {
325df930be7Sderaadt cd9660_tstamp_conv7(isodir->date,&inop->inode.iso_ctime);
326df930be7Sderaadt inop->inode.iso_atime = inop->inode.iso_ctime;
327df930be7Sderaadt inop->inode.iso_mtime = inop->inode.iso_ctime;
328df930be7Sderaadt }
329df930be7Sderaadt if (bp2)
330df930be7Sderaadt brelse(bp2);
331df930be7Sderaadt }
332df930be7Sderaadt
333df930be7Sderaadt int
cd9660_tstamp_conv7(u_char * pi,struct timespec * pu)3341bf87d88Sjsg cd9660_tstamp_conv7(u_char *pi, struct timespec *pu)
335df930be7Sderaadt {
336df930be7Sderaadt int crtime, days;
3371009d266Sderaadt int y, m, d, hour, minute, second;
3381009d266Sderaadt signed char tz;
339df930be7Sderaadt
340df930be7Sderaadt y = pi[0] + 1900;
341df930be7Sderaadt m = pi[1];
342df930be7Sderaadt d = pi[2];
343df930be7Sderaadt hour = pi[3];
344df930be7Sderaadt minute = pi[4];
345df930be7Sderaadt second = pi[5];
3461009d266Sderaadt tz = (signed char) pi[6];
347df930be7Sderaadt
348df930be7Sderaadt if (y < 1970) {
3499d71829cSniklas pu->tv_sec = 0;
3509d71829cSniklas pu->tv_nsec = 0;
351053e05a2Sniklas return (0);
352df930be7Sderaadt } else {
353df930be7Sderaadt #ifdef ORIGINAL
354df930be7Sderaadt /* computes day number relative to Sept. 19th,1989 */
355df930be7Sderaadt /* don't even *THINK* about changing formula. It works! */
356df930be7Sderaadt days = 367*(y-1980)-7*(y+(m+9)/12)/4-3*((y+(m-9)/7)/100+1)/4+275*m/9+d-100;
357df930be7Sderaadt #else
358df930be7Sderaadt /*
359df930be7Sderaadt * Changed :-) to make it relative to Jan. 1st, 1970
360df930be7Sderaadt * and to disambiguate negative division
361df930be7Sderaadt */
362df930be7Sderaadt days = 367*(y-1960)-7*(y+(m+9)/12)/4-3*((y+(m+9)/12-1)/100+1)/4+275*m/9+d-239;
363df930be7Sderaadt #endif
364df930be7Sderaadt crtime = ((((days * 24) + hour) * 60 + minute) * 60) + second;
365df930be7Sderaadt
366df930be7Sderaadt /* timezone offset is unreliable on some disks */
367df930be7Sderaadt if (-48 <= tz && tz <= 52)
368df930be7Sderaadt crtime -= tz * 15 * 60;
369df930be7Sderaadt }
3709d71829cSniklas pu->tv_sec = crtime;
3719d71829cSniklas pu->tv_nsec = 0;
372053e05a2Sniklas return (1);
373df930be7Sderaadt }
374df930be7Sderaadt
375df930be7Sderaadt static u_int
cd9660_chars2ui(u_char * begin,int len)3761bf87d88Sjsg cd9660_chars2ui(u_char *begin, int len)
377df930be7Sderaadt {
378df930be7Sderaadt u_int rc;
379df930be7Sderaadt
380df930be7Sderaadt for (rc = 0; --len >= 0;) {
381df930be7Sderaadt rc *= 10;
382df930be7Sderaadt rc += *begin++ - '0';
383df930be7Sderaadt }
384053e05a2Sniklas return (rc);
385df930be7Sderaadt }
386df930be7Sderaadt
387df930be7Sderaadt int
cd9660_tstamp_conv17(u_char * pi,struct timespec * pu)3881bf87d88Sjsg cd9660_tstamp_conv17(u_char *pi, struct timespec *pu)
389df930be7Sderaadt {
390df930be7Sderaadt u_char buf[7];
391df930be7Sderaadt
392df930be7Sderaadt /* year:"0001"-"9999" -> -1900 */
393df930be7Sderaadt buf[0] = cd9660_chars2ui(pi,4) - 1900;
394df930be7Sderaadt
395df930be7Sderaadt /* month: " 1"-"12" -> 1 - 12 */
396df930be7Sderaadt buf[1] = cd9660_chars2ui(pi + 4,2);
397df930be7Sderaadt
398df930be7Sderaadt /* day: " 1"-"31" -> 1 - 31 */
399df930be7Sderaadt buf[2] = cd9660_chars2ui(pi + 6,2);
400df930be7Sderaadt
401df930be7Sderaadt /* hour: " 0"-"23" -> 0 - 23 */
402df930be7Sderaadt buf[3] = cd9660_chars2ui(pi + 8,2);
403df930be7Sderaadt
404df930be7Sderaadt /* minute:" 0"-"59" -> 0 - 59 */
405df930be7Sderaadt buf[4] = cd9660_chars2ui(pi + 10,2);
406df930be7Sderaadt
407df930be7Sderaadt /* second:" 0"-"59" -> 0 - 59 */
408df930be7Sderaadt buf[5] = cd9660_chars2ui(pi + 12,2);
409df930be7Sderaadt
410df930be7Sderaadt /* difference of GMT */
411df930be7Sderaadt buf[6] = pi[16];
412df930be7Sderaadt
413053e05a2Sniklas return (cd9660_tstamp_conv7(buf,pu));
414df930be7Sderaadt }
415df930be7Sderaadt
4160cad8b22Sguenther cdino_t
isodirino(struct iso_directory_record * isodir,struct iso_mnt * imp)4171bf87d88Sjsg isodirino(struct iso_directory_record *isodir, struct iso_mnt *imp)
418df930be7Sderaadt {
4190cad8b22Sguenther cdino_t ino;
420df930be7Sderaadt
421053e05a2Sniklas ino = (isonum_733(isodir->extent) +
422053e05a2Sniklas isonum_711(isodir->ext_attr_length)) << imp->im_bshift;
423df930be7Sderaadt return (ino);
424df930be7Sderaadt }
425