xref: /freebsd/sys/fs/udf/udf_vnops.c (revision 6b3455a7665208c366849f0b2b3bc916fb97516e)
1 /*-
2  * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 /* udf_vnops.c */
30 /* Take care of the vnode side of things */
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/namei.h>
35 #include <sys/kernel.h>
36 #include <sys/malloc.h>
37 #include <sys/stat.h>
38 #include <sys/bio.h>
39 #include <sys/buf.h>
40 #include <sys/iconv.h>
41 #include <sys/mount.h>
42 #include <sys/vnode.h>
43 #include <sys/dirent.h>
44 #include <sys/queue.h>
45 #include <sys/unistd.h>
46 #include <sys/endian.h>
47 
48 #include <vm/uma.h>
49 
50 #include <fs/udf/ecma167-udf.h>
51 #include <fs/udf/osta.h>
52 #include <fs/udf/udf.h>
53 #include <fs/udf/udf_mount.h>
54 
55 extern struct iconv_functions *udf_iconv;
56 
57 static int udf_access(struct vop_access_args *);
58 static int udf_getattr(struct vop_getattr_args *);
59 static int udf_ioctl(struct vop_ioctl_args *);
60 static int udf_pathconf(struct vop_pathconf_args *);
61 static int udf_read(struct vop_read_args *);
62 static int udf_readdir(struct vop_readdir_args *);
63 static int udf_readlink(struct vop_readlink_args *ap);
64 static int udf_strategy(struct vop_strategy_args *);
65 static int udf_bmap(struct vop_bmap_args *);
66 static int udf_lookup(struct vop_cachedlookup_args *);
67 static int udf_reclaim(struct vop_reclaim_args *);
68 static int udf_readatoffset(struct udf_node *, int *, int, struct buf **, uint8_t **);
69 static int udf_bmap_internal(struct udf_node *, uint32_t, daddr_t *, uint32_t *);
70 
71 vop_t **udf_vnodeop_p;
72 static struct vnodeopv_entry_desc udf_vnodeop_entries[] = {
73 	{ &vop_default_desc,		(vop_t *) vop_defaultop },
74 	{ &vop_access_desc,		(vop_t *) udf_access },
75 	{ &vop_bmap_desc,		(vop_t *) udf_bmap },
76 	{ &vop_cachedlookup_desc,	(vop_t *) udf_lookup },
77 	{ &vop_getattr_desc,		(vop_t *) udf_getattr },
78 	{ &vop_ioctl_desc,		(vop_t *) udf_ioctl },
79 	{ &vop_lookup_desc,		(vop_t *) vfs_cache_lookup },
80 	{ &vop_pathconf_desc,		(vop_t *) udf_pathconf },
81 	{ &vop_read_desc,		(vop_t *) udf_read },
82 	{ &vop_readdir_desc,		(vop_t *) udf_readdir },
83 	{ &vop_readlink_desc,		(vop_t *) udf_readlink },
84 	{ &vop_reclaim_desc,		(vop_t *) udf_reclaim },
85 	{ &vop_strategy_desc,		(vop_t *) udf_strategy },
86 	{ NULL, NULL }
87 };
88 static struct vnodeopv_desc udf_vnodeop_opv_desc =
89 	{ &udf_vnodeop_p, udf_vnodeop_entries };
90 VNODEOP_SET(udf_vnodeop_opv_desc);
91 
92 MALLOC_DEFINE(M_UDFFID, "UDF FID", "UDF FileId structure");
93 MALLOC_DEFINE(M_UDFDS, "UDF DS", "UDF Dirstream structure");
94 
95 #define UDF_INVALID_BMAP	-1
96 
97 /* Look up a udf_node based on the ino_t passed in and return it's vnode */
98 int
99 udf_hashlookup(struct udf_mnt *udfmp, ino_t id, int flags, struct vnode **vpp)
100 {
101 	struct udf_node *node;
102 	struct udf_hash_lh *lh;
103 	int error;
104 
105 	*vpp = NULL;
106 
107 loop:
108 	mtx_lock(&udfmp->hash_mtx);
109 	lh = &udfmp->hashtbl[id % udfmp->hashsz];
110 	if (lh == NULL)
111 		return (ENOENT);
112 	LIST_FOREACH(node, lh, le) {
113 		if (node->hash_id == id) {
114 			VI_LOCK(node->i_vnode);
115 			mtx_unlock(&udfmp->hash_mtx);
116 			error = vget(node->i_vnode, flags | LK_INTERLOCK,
117 			    curthread);
118 			if (error == ENOENT)
119 				goto loop;
120 			if (error)
121 				return (error);
122 			*vpp = node->i_vnode;
123 			return (0);
124 		}
125 	}
126 
127 	mtx_unlock(&udfmp->hash_mtx);
128 	return (0);
129 }
130 
131 int
132 udf_hashins(struct udf_node *node)
133 {
134 	struct udf_mnt *udfmp;
135 	struct udf_hash_lh *lh;
136 
137 	udfmp = node->udfmp;
138 
139 	vn_lock(node->i_vnode, LK_EXCLUSIVE | LK_RETRY, curthread);
140 	mtx_lock(&udfmp->hash_mtx);
141 	lh = &udfmp->hashtbl[node->hash_id % udfmp->hashsz];
142 	if (lh == NULL)
143 		LIST_INIT(lh);
144 	LIST_INSERT_HEAD(lh, node, le);
145 	mtx_unlock(&udfmp->hash_mtx);
146 
147 	return (0);
148 }
149 
150 int
151 udf_hashrem(struct udf_node *node)
152 {
153 	struct udf_mnt *udfmp;
154 	struct udf_hash_lh *lh;
155 
156 	udfmp = node->udfmp;
157 
158 	mtx_lock(&udfmp->hash_mtx);
159 	lh = &udfmp->hashtbl[node->hash_id % udfmp->hashsz];
160 	if (lh == NULL)
161 		panic("hash entry is NULL, node->hash_id= %d\n", node->hash_id);
162 	LIST_REMOVE(node, le);
163 	mtx_unlock(&udfmp->hash_mtx);
164 
165 	return (0);
166 }
167 
168 int
169 udf_allocv(struct mount *mp, struct vnode **vpp, struct thread *td)
170 {
171 	int error;
172 	struct vnode *vp;
173 
174 	error = getnewvnode("udf", mp, udf_vnodeop_p, &vp);
175 	if (error) {
176 		printf("udf_allocv: failed to allocate new vnode\n");
177 		return (error);
178 	}
179 
180 	*vpp = vp;
181 	return (0);
182 }
183 
184 /* Convert file entry permission (5 bits per owner/group/user) to a mode_t */
185 static mode_t
186 udf_permtomode(struct udf_node *node)
187 {
188 	uint32_t perm;
189 	uint16_t flags;
190 	mode_t mode;
191 
192 	perm = le32toh(node->fentry->perm);
193 	flags = le16toh(node->fentry->icbtag.flags);
194 
195 	mode = perm & UDF_FENTRY_PERM_USER_MASK;
196 	mode |= ((perm & UDF_FENTRY_PERM_GRP_MASK) >> 2);
197 	mode |= ((perm & UDF_FENTRY_PERM_OWNER_MASK) >> 4);
198 	mode |= ((flags & UDF_ICB_TAG_FLAGS_STICKY) << 4);
199 	mode |= ((flags & UDF_ICB_TAG_FLAGS_SETGID) << 6);
200 	mode |= ((flags & UDF_ICB_TAG_FLAGS_SETUID) << 8);
201 
202 	return (mode);
203 }
204 
205 static int
206 udf_access(struct vop_access_args *a)
207 {
208 	struct vnode *vp;
209 	struct udf_node *node;
210 	mode_t a_mode, mode;
211 
212 	vp = a->a_vp;
213 	node = VTON(vp);
214 	a_mode = a->a_mode;
215 
216 	if (a_mode & VWRITE) {
217 		switch (vp->v_type) {
218 		case VDIR:
219 		case VLNK:
220 		case VREG:
221 			return (EROFS);
222 			/* NOT REACHED */
223 		default:
224 			break;
225 		}
226 	}
227 
228 	mode = udf_permtomode(node);
229 
230 	return (vaccess(vp->v_type, mode, node->fentry->uid, node->fentry->gid,
231 	    a_mode, a->a_cred, NULL));
232 }
233 
234 static int mon_lens[2][12] = {
235 	{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
236 	{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
237 };
238 
239 static int
240 udf_isaleapyear(int year)
241 {
242 	int i;
243 
244 	i = (year % 4) ? 0 : 1;
245 	i &= (year % 100) ? 1 : 0;
246 	i |= (year % 400) ? 0 : 1;
247 
248 	return i;
249 }
250 
251 /*
252  * XXX This is just a rough hack.  Daylight savings isn't calculated and tv_nsec
253  * is ignored.
254  * Timezone calculation compliments of Julian Elischer <julian@elischer.org>.
255  */
256 static void
257 udf_timetotimespec(struct timestamp *time, struct timespec *t)
258 {
259 	int i, lpyear, daysinyear, year;
260 	union {
261 		uint16_t	u_tz_offset;
262 		int16_t		s_tz_offset;
263 	} tz;
264 
265 	t->tv_nsec = 0;
266 
267 	/* DirectCD seems to like using bogus year values */
268 	year = le16toh(time->year);
269 	if (year < 1970) {
270 		t->tv_sec = 0;
271 		return;
272 	}
273 
274 	/* Calculate the time and day */
275 	t->tv_sec = time->second;
276 	t->tv_sec += time->minute * 60;
277 	t->tv_sec += time->hour * 3600;
278 	t->tv_sec += time->day * 3600 * 24;
279 
280 	/* Calclulate the month */
281 	lpyear = udf_isaleapyear(year);
282 	for (i = 1; i < time->month; i++)
283 		t->tv_sec += mon_lens[lpyear][i] * 3600 * 24;
284 
285 	/* Speed up the calculation */
286 	if (year > 1979)
287 		t->tv_sec += 315532800;
288 	if (year > 1989)
289 		t->tv_sec += 315619200;
290 	if (year > 1999)
291 		t->tv_sec += 315532800;
292 	for (i = 2000; i < year; i++) {
293 		daysinyear = udf_isaleapyear(i) + 365 ;
294 		t->tv_sec += daysinyear * 3600 * 24;
295 	}
296 
297 	/*
298 	 * Calculate the time zone.  The timezone is 12 bit signed 2's
299 	 * compliment, so we gotta do some extra magic to handle it right.
300 	 */
301 	tz.u_tz_offset = le16toh(time->type_tz);
302 	tz.u_tz_offset &= 0x0fff;
303 	if (tz.u_tz_offset & 0x0800)
304 		tz.u_tz_offset |= 0xf000;	/* extend the sign to 16 bits */
305 	if ((time->type_tz & 0x1000) && (tz.s_tz_offset != -2047))
306 		t->tv_sec -= tz.s_tz_offset * 60;
307 
308 	return;
309 }
310 
311 static int
312 udf_getattr(struct vop_getattr_args *a)
313 {
314 	struct vnode *vp;
315 	struct udf_node *node;
316 	struct vattr *vap;
317 	struct file_entry *fentry;
318 	struct timespec ts;
319 
320 	ts.tv_sec = 0;
321 
322 	vp = a->a_vp;
323 	vap = a->a_vap;
324 	node = VTON(vp);
325 	fentry = node->fentry;
326 
327 	vap->va_fsid = dev2udev(node->i_dev);
328 	vap->va_fileid = node->hash_id;
329 	vap->va_mode = udf_permtomode(node);
330 	vap->va_nlink = le16toh(fentry->link_cnt);
331 	/*
332 	 * XXX The spec says that -1 is valid for uid/gid and indicates an
333 	 * invalid uid/gid.  How should this be represented?
334 	 */
335 	vap->va_uid = (le32toh(fentry->uid) == -1) ? 0 : le32toh(fentry->uid);
336 	vap->va_gid = (le32toh(fentry->gid) == -1) ? 0 : le32toh(fentry->gid);
337 	udf_timetotimespec(&fentry->atime, &vap->va_atime);
338 	udf_timetotimespec(&fentry->mtime, &vap->va_mtime);
339 	vap->va_ctime = vap->va_mtime; /* XXX Stored as an Extended Attribute */
340 	vap->va_rdev = 0; /* XXX */
341 	if (vp->v_type & VDIR) {
342 		/*
343 		 * Directories that are recorded within their ICB will show
344 		 * as having 0 blocks recorded.  Since tradition dictates
345 		 * that directories consume at least one logical block,
346 		 * make it appear so.
347 		 */
348 		if (fentry->logblks_rec != 0) {
349 			vap->va_size =
350 			    le64toh(fentry->logblks_rec) * node->udfmp->bsize;
351 		} else {
352 			vap->va_size = node->udfmp->bsize;
353 		}
354 	} else {
355 		vap->va_size = le64toh(fentry->inf_len);
356 	}
357 	vap->va_flags = 0;
358 	vap->va_gen = 1;
359 	vap->va_blocksize = node->udfmp->bsize;
360 	vap->va_bytes = le64toh(fentry->inf_len);
361 	vap->va_type = vp->v_type;
362 	vap->va_filerev = 0; /* XXX */
363 	return (0);
364 }
365 
366 /*
367  * File specific ioctls.
368  */
369 static int
370 udf_ioctl(struct vop_ioctl_args *a)
371 {
372 	printf("%s called\n", __func__);
373 	return (ENOTTY);
374 }
375 
376 /*
377  * I'm not sure that this has much value in a read-only filesystem, but
378  * cd9660 has it too.
379  */
380 static int
381 udf_pathconf(struct vop_pathconf_args *a)
382 {
383 
384 	switch (a->a_name) {
385 	case _PC_LINK_MAX:
386 		*a->a_retval = 65535;
387 		return (0);
388 	case _PC_NAME_MAX:
389 		*a->a_retval = NAME_MAX;
390 		return (0);
391 	case _PC_PATH_MAX:
392 		*a->a_retval = PATH_MAX;
393 		return (0);
394 	case _PC_NO_TRUNC:
395 		*a->a_retval = 1;
396 		return (0);
397 	default:
398 		return (EINVAL);
399 	}
400 }
401 
402 static int
403 udf_read(struct vop_read_args *a)
404 {
405 	struct vnode *vp = a->a_vp;
406 	struct uio *uio = a->a_uio;
407 	struct udf_node *node = VTON(vp);
408 	struct buf *bp;
409 	uint8_t *data;
410 	int error = 0;
411 	int size, fsize, offset;
412 
413 	if (uio->uio_offset < 0)
414 		return (EINVAL);
415 
416 	fsize = le64toh(node->fentry->inf_len);
417 
418 	while (uio->uio_offset < fsize && uio->uio_resid > 0) {
419 		offset = uio->uio_offset;
420 		size = uio->uio_resid;
421 		error = udf_readatoffset(node, &size, offset, &bp, &data);
422 		if (error == 0)
423 			error = uiomove(data, size, uio);
424 		if (bp != NULL)
425 			brelse(bp);
426 		if (error)
427 			break;
428 	};
429 
430 	return (error);
431 }
432 
433 /*
434  * Call the OSTA routines to translate the name from a CS0 dstring to a
435  * 16-bit Unicode String.  Hooks need to be placed in here to translate from
436  * Unicode to the encoding that the kernel/user expects.  Return the length
437  * of the translated string.
438  */
439 static int
440 udf_transname(char *cs0string, char *destname, int len, struct udf_mnt *udfmp)
441 {
442 	unicode_t *transname;
443 	char *unibuf, *unip;
444 	int i, unilen = 0, destlen;
445 	size_t destleft = MAXNAMLEN;
446 
447 	/* Convert 16-bit Unicode to destname */
448 	if (udfmp->im_flags & UDFMNT_KICONV && udf_iconv) {
449 		/* allocate a buffer big enough to hold an 8->16 bit expansion */
450 		unibuf = uma_zalloc(udf_zone_trans, M_WAITOK);
451 		unip = unibuf;
452 		if ((unilen = udf_UncompressUnicodeByte(len, cs0string, unibuf)) == -1) {
453 			printf("udf: Unicode translation failed\n");
454 			uma_zfree(udf_zone_trans, unibuf);
455 			return 0;
456 		}
457 
458 		while (unilen > 0 && destleft > 0) {
459 			udf_iconv->conv(udfmp->im_d2l, (const char **)&unibuf,
460 				(size_t *)&unilen, (char **)&destname, &destleft);
461 			/* Unconverted character found */
462 			if (unilen > 0 && destleft > 0) {
463 				*destname++ = '?';
464 				destleft--;
465 				unibuf += 2;
466 				unilen -= 2;
467 			}
468 		}
469 		uma_zfree(udf_zone_trans, unip);
470 		*destname = '\0';
471 		destlen = MAXNAMLEN - (int)destleft;
472 	} else {
473 		/* allocate a buffer big enough to hold an 8->16 bit expansion */
474 		transname = uma_zalloc(udf_zone_trans, M_WAITOK);
475 
476 		if ((unilen = udf_UncompressUnicode(len, cs0string, transname)) == -1) {
477 			printf("udf: Unicode translation failed\n");
478 			uma_zfree(udf_zone_trans, transname);
479 			return 0;
480 		}
481 
482 		for (i = 0; i < unilen ; i++) {
483 			if (transname[i] & 0xff00) {
484 				destname[i] = '.';	/* Fudge the 16bit chars */
485 			} else {
486 				destname[i] = transname[i] & 0xff;
487 			}
488 		}
489 		uma_zfree(udf_zone_trans, transname);
490 		destname[unilen] = 0;
491 		destlen = unilen;
492 	}
493 
494 	return (destlen);
495 }
496 
497 /*
498  * Compare a CS0 dstring with a name passed in from the VFS layer.  Return
499  * 0 on a successful match, nonzero therwise.  Unicode work may need to be done
500  * here also.
501  */
502 static int
503 udf_cmpname(char *cs0string, char *cmpname, int cs0len, int cmplen, struct udf_mnt *udfmp)
504 {
505 	char *transname;
506 	int error = 0;
507 
508 	/* This is overkill, but not worth creating a new zone */
509 	transname = uma_zalloc(udf_zone_trans, M_WAITOK);
510 
511 	cs0len = udf_transname(cs0string, transname, cs0len, udfmp);
512 
513 	/* Easy check.  If they aren't the same length, they aren't equal */
514 	if ((cs0len == 0) || (cs0len != cmplen))
515 		error = -1;
516 	else
517 		error = bcmp(transname, cmpname, cmplen);
518 
519 	uma_zfree(udf_zone_trans, transname);
520 	return (error);
521 }
522 
523 struct udf_uiodir {
524 	struct dirent *dirent;
525 	u_long *cookies;
526 	int ncookies;
527 	int acookies;
528 	int eofflag;
529 };
530 
531 static int
532 udf_uiodir(struct udf_uiodir *uiodir, int de_size, struct uio *uio, long cookie)
533 {
534 	if (uiodir->cookies != NULL) {
535 		if (++uiodir->acookies > uiodir->ncookies) {
536 			uiodir->eofflag = 0;
537 			return (-1);
538 		}
539 		*uiodir->cookies++ = cookie;
540 	}
541 
542 	if (uio->uio_resid < de_size) {
543 		uiodir->eofflag = 0;
544 		return (-1);
545 	}
546 
547 	return (uiomove(uiodir->dirent, de_size, uio));
548 }
549 
550 static struct udf_dirstream *
551 udf_opendir(struct udf_node *node, int offset, int fsize, struct udf_mnt *udfmp)
552 {
553 	struct udf_dirstream *ds;
554 
555 	ds = uma_zalloc(udf_zone_ds, M_WAITOK | M_ZERO);
556 
557 	ds->node = node;
558 	ds->offset = offset;
559 	ds->udfmp = udfmp;
560 	ds->fsize = fsize;
561 
562 	return (ds);
563 }
564 
565 static struct fileid_desc *
566 udf_getfid(struct udf_dirstream *ds)
567 {
568 	struct fileid_desc *fid;
569 	int error, frag_size = 0, total_fid_size;
570 
571 	/* End of directory? */
572 	if (ds->offset + ds->off >= ds->fsize) {
573 		ds->error = 0;
574 		return (NULL);
575 	}
576 
577 	/* Grab the first extent of the directory */
578 	if (ds->off == 0) {
579 		ds->size = 0;
580 		error = udf_readatoffset(ds->node, &ds->size, ds->offset,
581 		    &ds->bp, &ds->data);
582 		if (error) {
583 			ds->error = error;
584 			if (ds->bp != NULL)
585 				brelse(ds->bp);
586 			return (NULL);
587 		}
588 	}
589 
590 	/*
591 	 * Clean up from a previous fragmented FID.
592 	 * XXX Is this the right place for this?
593 	 */
594 	if (ds->fid_fragment && ds->buf != NULL) {
595 		ds->fid_fragment = 0;
596 		FREE(ds->buf, M_UDFFID);
597 	}
598 
599 	fid = (struct fileid_desc*)&ds->data[ds->off];
600 
601 	/*
602 	 * Check to see if the fid is fragmented. The first test
603 	 * ensures that we don't wander off the end of the buffer
604 	 * looking for the l_iu and l_fi fields.
605 	 */
606 	if (ds->off + UDF_FID_SIZE > ds->size ||
607 	    ds->off + le16toh(fid->l_iu) + fid->l_fi + UDF_FID_SIZE > ds->size){
608 
609 		/* Copy what we have of the fid into a buffer */
610 		frag_size = ds->size - ds->off;
611 		if (frag_size >= ds->udfmp->bsize) {
612 			printf("udf: invalid FID fragment\n");
613 			ds->error = EINVAL;
614 			return (NULL);
615 		}
616 
617 		/*
618 		 * File ID descriptors can only be at most one
619 		 * logical sector in size.
620 		 */
621 		MALLOC(ds->buf, uint8_t*, ds->udfmp->bsize, M_UDFFID,
622 		     M_WAITOK | M_ZERO);
623 		bcopy(fid, ds->buf, frag_size);
624 
625 		/* Reduce all of the casting magic */
626 		fid = (struct fileid_desc*)ds->buf;
627 
628 		if (ds->bp != NULL)
629 			brelse(ds->bp);
630 
631 		/* Fetch the next allocation */
632 		ds->offset += ds->size;
633 		ds->size = 0;
634 		error = udf_readatoffset(ds->node, &ds->size, ds->offset,
635 		    &ds->bp, &ds->data);
636 		if (error) {
637 			ds->error = error;
638 			return (NULL);
639 		}
640 
641 		/*
642 		 * If the fragment was so small that we didn't get
643 		 * the l_iu and l_fi fields, copy those in.
644 		 */
645 		if (frag_size < UDF_FID_SIZE)
646 			bcopy(ds->data, &ds->buf[frag_size],
647 			    UDF_FID_SIZE - frag_size);
648 
649 		/*
650 		 * Now that we have enough of the fid to work with,
651 		 * copy in the rest of the fid from the new
652 		 * allocation.
653 		 */
654 		total_fid_size = UDF_FID_SIZE + le16toh(fid->l_iu) + fid->l_fi;
655 		if (total_fid_size > ds->udfmp->bsize) {
656 			printf("udf: invalid FID\n");
657 			ds->error = EIO;
658 			return (NULL);
659 		}
660 		bcopy(ds->data, &ds->buf[frag_size],
661 		    total_fid_size - frag_size);
662 
663 		ds->fid_fragment = 1;
664 	} else {
665 		total_fid_size = le16toh(fid->l_iu) + fid->l_fi + UDF_FID_SIZE;
666 	}
667 
668 	/*
669 	 * Update the offset. Align on a 4 byte boundary because the
670 	 * UDF spec says so.
671 	 */
672 	ds->this_off = ds->off;
673 	if (!ds->fid_fragment) {
674 		ds->off += (total_fid_size + 3) & ~0x03;
675 	} else {
676 		ds->off = (total_fid_size - frag_size + 3) & ~0x03;
677 	}
678 
679 	return (fid);
680 }
681 
682 static void
683 udf_closedir(struct udf_dirstream *ds)
684 {
685 
686 	if (ds->bp != NULL)
687 		brelse(ds->bp);
688 
689 	if (ds->fid_fragment && ds->buf != NULL)
690 		FREE(ds->buf, M_UDFFID);
691 
692 	uma_zfree(udf_zone_ds, ds);
693 }
694 
695 static int
696 udf_readdir(struct vop_readdir_args *a)
697 {
698 	struct vnode *vp;
699 	struct uio *uio;
700 	struct dirent dir;
701 	struct udf_node *node;
702 	struct udf_mnt *udfmp;
703 	struct fileid_desc *fid;
704 	struct udf_uiodir uiodir;
705 	struct udf_dirstream *ds;
706 	u_long *cookies = NULL;
707 	int ncookies;
708 	int error = 0;
709 
710 	vp = a->a_vp;
711 	uio = a->a_uio;
712 	node = VTON(vp);
713 	udfmp = node->udfmp;
714 	uiodir.eofflag = 1;
715 
716 	if (a->a_ncookies != NULL) {
717 		/*
718 		 * Guess how many entries are needed.  If we run out, this
719 		 * function will be called again and thing will pick up were
720 		 * it left off.
721 		 */
722 		ncookies = uio->uio_resid / 8;
723 		MALLOC(cookies, u_long *, sizeof(u_long) * ncookies,
724 		    M_TEMP, M_WAITOK);
725 		if (cookies == NULL)
726 			return (ENOMEM);
727 		uiodir.ncookies = ncookies;
728 		uiodir.cookies = cookies;
729 		uiodir.acookies = 0;
730 	} else {
731 		uiodir.cookies = NULL;
732 	}
733 
734 	/*
735 	 * Iterate through the file id descriptors.  Give the parent dir
736 	 * entry special attention.
737 	 */
738 	ds = udf_opendir(node, uio->uio_offset, le64toh(node->fentry->inf_len),
739 	    node->udfmp);
740 
741 	while ((fid = udf_getfid(ds)) != NULL) {
742 
743 		/* XXX Should we return an error on a bad fid? */
744 		if (udf_checktag(&fid->tag, TAGID_FID)) {
745 			printf("Invalid FID tag\n");
746 			hexdump(fid, UDF_FID_SIZE, NULL, 0);
747 			error = EIO;
748 			break;
749 		}
750 
751 		/* Is this a deleted file? */
752 		if (fid->file_char & UDF_FILE_CHAR_DEL)
753 			continue;
754 
755 		if ((fid->l_fi == 0) && (fid->file_char & UDF_FILE_CHAR_PAR)) {
756 			/* Do up the '.' and '..' entries.  Dummy values are
757 			 * used for the cookies since the offset here is
758 			 * usually zero, and NFS doesn't like that value
759 			 */
760 			dir.d_fileno = node->hash_id;
761 			dir.d_type = DT_DIR;
762 			dir.d_name[0] = '.';
763 			dir.d_namlen = 1;
764 			dir.d_reclen = GENERIC_DIRSIZ(&dir);
765 			uiodir.dirent = &dir;
766 			error = udf_uiodir(&uiodir, dir.d_reclen, uio, 1);
767 			if (error)
768 				break;
769 
770 			dir.d_fileno = udf_getid(&fid->icb);
771 			dir.d_type = DT_DIR;
772 			dir.d_name[0] = '.';
773 			dir.d_name[1] = '.';
774 			dir.d_namlen = 2;
775 			dir.d_reclen = GENERIC_DIRSIZ(&dir);
776 			uiodir.dirent = &dir;
777 			error = udf_uiodir(&uiodir, dir.d_reclen, uio, 2);
778 		} else {
779 			dir.d_namlen = udf_transname(&fid->data[fid->l_iu],
780 			    &dir.d_name[0], fid->l_fi, udfmp);
781 			dir.d_fileno = udf_getid(&fid->icb);
782 			dir.d_type = (fid->file_char & UDF_FILE_CHAR_DIR) ?
783 			    DT_DIR : DT_UNKNOWN;
784 			dir.d_reclen = GENERIC_DIRSIZ(&dir);
785 			uiodir.dirent = &dir;
786 			error = udf_uiodir(&uiodir, dir.d_reclen, uio,
787 			    ds->this_off);
788 		}
789 		if (error) {
790 			printf("uiomove returned %d\n", error);
791 			break;
792 		}
793 
794 	}
795 
796 	/* tell the calling layer whether we need to be called again */
797 	*a->a_eofflag = uiodir.eofflag;
798 	uio->uio_offset = ds->offset + ds->off;
799 
800 	if (!error)
801 		error = ds->error;
802 
803 	udf_closedir(ds);
804 
805 	if (a->a_ncookies != NULL) {
806 		if (error)
807 			FREE(cookies, M_TEMP);
808 		else {
809 			*a->a_ncookies = uiodir.acookies;
810 			*a->a_cookies = cookies;
811 		}
812 	}
813 
814 	return (error);
815 }
816 
817 /* Are there any implementations out there that do soft-links? */
818 static int
819 udf_readlink(struct vop_readlink_args *ap)
820 {
821 	printf("%s called\n", __func__);
822 	return (EOPNOTSUPP);
823 }
824 
825 static int
826 udf_strategy(struct vop_strategy_args *a)
827 {
828 	struct buf *bp;
829 	struct vnode *vp;
830 	struct udf_node *node;
831 	int maxsize;
832 
833 	bp = a->a_bp;
834 	vp = bp->b_vp;
835 	node = VTON(vp);
836 
837 	KASSERT(a->a_vp == a->a_bp->b_vp, ("%s(%p != %p)",
838 	    __func__, a->a_vp, a->a_bp->b_vp));
839 	/* cd9660 has this test reversed, but it seems more logical this way */
840 	if (bp->b_blkno != bp->b_lblkno) {
841 		/*
842 		 * Files that are embedded in the fentry don't translate well
843 		 * to a block number.  Reject.
844 		 */
845 		if (udf_bmap_internal(node, bp->b_lblkno * node->udfmp->bsize,
846 		    &bp->b_lblkno, &maxsize)) {
847 			clrbuf(bp);
848 			bp->b_blkno = -1;
849 		}
850 	}
851 	if ((long)bp->b_blkno == -1) {
852 		bufdone(bp);
853 		return (0);
854 	}
855 	vp = node->i_devvp;
856 	bp->b_dev = vp->v_rdev;
857 	bp->b_iooffset = dbtob(bp->b_blkno);
858 	VOP_SPECSTRATEGY(vp, bp);
859 	return (0);
860 }
861 
862 static int
863 udf_bmap(struct vop_bmap_args *a)
864 {
865 	struct udf_node *node;
866 	uint32_t max_size;
867 	daddr_t lsector;
868 	int error;
869 
870 	node = VTON(a->a_vp);
871 
872 	if (a->a_vpp != NULL)
873 		*a->a_vpp = node->i_devvp;
874 	if (a->a_bnp == NULL)
875 		return (0);
876 	if (a->a_runb)
877 		*a->a_runb = 0;
878 
879 	error = udf_bmap_internal(node, a->a_bn * node->udfmp->bsize, &lsector,
880 	    &max_size);
881 	if (error)
882 		return (error);
883 
884 	/* Translate logical to physical sector number */
885 	*a->a_bnp = lsector << (node->udfmp->bshift - DEV_BSHIFT);
886 
887 	/* Punt on read-ahead for now */
888 	if (a->a_runp)
889 		*a->a_runp = 0;
890 
891 	return (0);
892 }
893 
894 /*
895  * The all powerful VOP_LOOKUP().
896  */
897 static int
898 udf_lookup(struct vop_cachedlookup_args *a)
899 {
900 	struct vnode *dvp;
901 	struct vnode *tdp = NULL;
902 	struct vnode **vpp = a->a_vpp;
903 	struct udf_node *node;
904 	struct udf_mnt *udfmp;
905 	struct fileid_desc *fid = NULL;
906 	struct udf_dirstream *ds;
907 	struct thread *td;
908 	u_long nameiop;
909 	u_long flags;
910 	char *nameptr;
911 	long namelen;
912 	ino_t id = 0;
913 	int offset, error = 0;
914 	int numdirpasses, fsize;
915 
916 	dvp = a->a_dvp;
917 	node = VTON(dvp);
918 	udfmp = node->udfmp;
919 	nameiop = a->a_cnp->cn_nameiop;
920 	flags = a->a_cnp->cn_flags;
921 	nameptr = a->a_cnp->cn_nameptr;
922 	namelen = a->a_cnp->cn_namelen;
923 	fsize = le64toh(node->fentry->inf_len);
924 	td = a->a_cnp->cn_thread;
925 
926 	/*
927 	 * If this is a LOOKUP and we've already partially searched through
928 	 * the directory, pick up where we left off and flag that the
929 	 * directory may need to be searched twice.  For a full description,
930 	 * see /sys/isofs/cd9660/cd9660_lookup.c:cd9660_lookup()
931 	 */
932 	if (nameiop != LOOKUP || node->diroff == 0 || node->diroff > fsize) {
933 		offset = 0;
934 		numdirpasses = 1;
935 	} else {
936 		offset = node->diroff;
937 		numdirpasses = 2;
938 		nchstats.ncs_2passes++;
939 	}
940 
941 lookloop:
942 	ds = udf_opendir(node, offset, fsize, udfmp);
943 
944 	while ((fid = udf_getfid(ds)) != NULL) {
945 
946 		/* XXX Should we return an error on a bad fid? */
947 		if (udf_checktag(&fid->tag, TAGID_FID)) {
948 			printf("udf_lookup: Invalid tag\n");
949 			error = EIO;
950 			break;
951 		}
952 
953 		/* Is this a deleted file? */
954 		if (fid->file_char & UDF_FILE_CHAR_DEL)
955 			continue;
956 
957 		if ((fid->l_fi == 0) && (fid->file_char & UDF_FILE_CHAR_PAR)) {
958 			if (flags & ISDOTDOT) {
959 				id = udf_getid(&fid->icb);
960 				break;
961 			}
962 		} else {
963 			if (!(udf_cmpname(&fid->data[fid->l_iu],
964 			    nameptr, fid->l_fi, namelen, udfmp))) {
965 				id = udf_getid(&fid->icb);
966 				break;
967 			}
968 		}
969 	}
970 
971 	if (!error)
972 		error = ds->error;
973 
974 	/* XXX Bail out here? */
975 	if (error) {
976 		udf_closedir(ds);
977 		return (error);
978 	}
979 
980 	/* Did we have a match? */
981 	if (id) {
982 		error = udf_vget(udfmp->im_mountp, id, LK_EXCLUSIVE, &tdp);
983 		if (!error) {
984 			/*
985 			 * Remember where this entry was if it's the final
986 			 * component.
987 			 */
988 			if ((flags & ISLASTCN) && nameiop == LOOKUP)
989 				node->diroff = ds->offset + ds->off;
990 			if (numdirpasses == 2)
991 				nchstats.ncs_pass2++;
992 			if (!(flags & LOCKPARENT) || !(flags & ISLASTCN)) {
993 				a->a_cnp->cn_flags |= PDIRUNLOCK;
994 				VOP_UNLOCK(dvp, 0, td);
995 			}
996 
997 			*vpp = tdp;
998 
999 			/* Put this entry in the cache */
1000 			if (flags & MAKEENTRY)
1001 				cache_enter(dvp, *vpp, a->a_cnp);
1002 		}
1003 	} else {
1004 		/* Name wasn't found on this pass.  Do another pass? */
1005 		if (numdirpasses == 2) {
1006 			numdirpasses--;
1007 			offset = 0;
1008 			udf_closedir(ds);
1009 			goto lookloop;
1010 		}
1011 
1012 		/* Enter name into cache as non-existant */
1013 		if (flags & MAKEENTRY)
1014 			cache_enter(dvp, *vpp, a->a_cnp);
1015 
1016 		if ((flags & ISLASTCN) &&
1017 		    (nameiop == CREATE || nameiop == RENAME)) {
1018 			error = EROFS;
1019 		} else {
1020 			error = ENOENT;
1021 		}
1022 	}
1023 
1024 	udf_closedir(ds);
1025 	return (error);
1026 }
1027 
1028 static int
1029 udf_reclaim(struct vop_reclaim_args *a)
1030 {
1031 	struct vnode *vp;
1032 	struct udf_node *unode;
1033 
1034 	vp = a->a_vp;
1035 	unode = VTON(vp);
1036 
1037 	if (unode != NULL) {
1038 		udf_hashrem(unode);
1039 		if (unode->i_devvp) {
1040 			vrele(unode->i_devvp);
1041 			unode->i_devvp = 0;
1042 		}
1043 
1044 		if (unode->fentry != NULL)
1045 			FREE(unode->fentry, M_UDFFENTRY);
1046 		uma_zfree(udf_zone_node, unode);
1047 		vp->v_data = NULL;
1048 	}
1049 
1050 	return (0);
1051 }
1052 
1053 /*
1054  * Read the block and then set the data pointer to correspond with the
1055  * offset passed in.  Only read in at most 'size' bytes, and then set 'size'
1056  * to the number of bytes pointed to.  If 'size' is zero, try to read in a
1057  * whole extent.
1058  *
1059  * Note that *bp may be assigned error or not.
1060  *
1061  */
1062 static int
1063 udf_readatoffset(struct udf_node *node, int *size, int offset, struct buf **bp, uint8_t **data)
1064 {
1065 	struct udf_mnt *udfmp;
1066 	struct file_entry *fentry = NULL;
1067 	struct buf *bp1;
1068 	uint32_t max_size;
1069 	daddr_t sector;
1070 	int error;
1071 
1072 	udfmp = node->udfmp;
1073 
1074 	*bp = NULL;
1075 	error = udf_bmap_internal(node, offset, &sector, &max_size);
1076 	if (error == UDF_INVALID_BMAP) {
1077 		/*
1078 		 * This error means that the file *data* is stored in the
1079 		 * allocation descriptor field of the file entry.
1080 		 */
1081 		fentry = node->fentry;
1082 		*data = &fentry->data[le32toh(fentry->l_ea)];
1083 		*size = le32toh(fentry->l_ad);
1084 		return (0);
1085 	} else if (error != 0) {
1086 		return (error);
1087 	}
1088 
1089 	/* Adjust the size so that it is within range */
1090 	if (*size == 0 || *size > max_size)
1091 		*size = max_size;
1092 	*size = min(*size, MAXBSIZE);
1093 
1094 	if ((error = udf_readlblks(udfmp, sector, *size, bp))) {
1095 		printf("warning: udf_readlblks returned error %d\n", error);
1096 		/* note: *bp may be non-NULL */
1097 		return (error);
1098 	}
1099 
1100 	bp1 = *bp;
1101 	*data = (uint8_t *)&bp1->b_data[offset % udfmp->bsize];
1102 	return (0);
1103 }
1104 
1105 /*
1106  * Translate a file offset into a logical block and then into a physical
1107  * block.
1108  */
1109 static int
1110 udf_bmap_internal(struct udf_node *node, uint32_t offset, daddr_t *sector, uint32_t *max_size)
1111 {
1112 	struct udf_mnt *udfmp;
1113 	struct file_entry *fentry;
1114 	void *icb;
1115 	struct icb_tag *tag;
1116 	uint32_t icblen = 0;
1117 	daddr_t lsector;
1118 	int ad_offset, ad_num = 0;
1119 	int i, p_offset;
1120 
1121 	udfmp = node->udfmp;
1122 	fentry = node->fentry;
1123 	tag = &fentry->icbtag;
1124 
1125 	switch (le16toh(tag->strat_type)) {
1126 	case 4:
1127 		break;
1128 
1129 	case 4096:
1130 		printf("Cannot deal with strategy4096 yet!\n");
1131 		return (ENODEV);
1132 
1133 	default:
1134 		printf("Unknown strategy type %d\n", tag->strat_type);
1135 		return (ENODEV);
1136 	}
1137 
1138 	switch (le16toh(tag->flags) & 0x7) {
1139 	case 0:
1140 		/*
1141 		 * The allocation descriptor field is filled with short_ad's.
1142 		 * If the offset is beyond the current extent, look for the
1143 		 * next extent.
1144 		 */
1145 		do {
1146 			offset -= icblen;
1147 			ad_offset = sizeof(struct short_ad) * ad_num;
1148 			if (ad_offset > le32toh(fentry->l_ad)) {
1149 				printf("File offset out of bounds\n");
1150 				return (EINVAL);
1151 			}
1152 			icb = GETICB(long_ad, fentry,
1153 			    le32toh(fentry->l_ea) + ad_offset);
1154 			icblen = GETICBLEN(short_ad, icb);
1155 			ad_num++;
1156 		} while(offset >= icblen);
1157 
1158 		lsector = (offset  >> udfmp->bshift) +
1159 		    ((struct short_ad *)(icb))->pos;
1160 
1161 		*max_size = GETICBLEN(short_ad, icb);
1162 
1163 		break;
1164 	case 1:
1165 		/*
1166 		 * The allocation descriptor field is filled with long_ad's
1167 		 * If the offset is beyond the current extent, look for the
1168 		 * next extent.
1169 		 */
1170 		do {
1171 			offset -= icblen;
1172 			ad_offset = sizeof(struct long_ad) * ad_num;
1173 			if (ad_offset > le32toh(fentry->l_ad)) {
1174 				printf("File offset out of bounds\n");
1175 				return (EINVAL);
1176 			}
1177 			icb = GETICB(long_ad, fentry,
1178 			    le32toh(fentry->l_ea) + ad_offset);
1179 			icblen = GETICBLEN(long_ad, icb);
1180 			ad_num++;
1181 		} while(offset >= icblen);
1182 
1183 		lsector = (offset >> udfmp->bshift) +
1184 		    le32toh(((struct long_ad *)(icb))->loc.lb_num);
1185 
1186 		*max_size = GETICBLEN(long_ad, icb);
1187 
1188 		break;
1189 	case 3:
1190 		/*
1191 		 * This type means that the file *data* is stored in the
1192 		 * allocation descriptor field of the file entry.
1193 		 */
1194 		*max_size = 0;
1195 		*sector = node->hash_id + udfmp->part_start;
1196 
1197 		return (UDF_INVALID_BMAP);
1198 	case 2:
1199 		/* DirectCD does not use extended_ad's */
1200 	default:
1201 		printf("Unsupported allocation descriptor %d\n",
1202 		       tag->flags & 0x7);
1203 		return (ENODEV);
1204 	}
1205 
1206 	*sector = lsector + udfmp->part_start;
1207 
1208 	/*
1209 	 * Check the sparing table.  Each entry represents the beginning of
1210 	 * a packet.
1211 	 */
1212 	if (udfmp->s_table != NULL) {
1213 		for (i = 0; i< udfmp->s_table_entries; i++) {
1214 			p_offset =
1215 			    lsector - le32toh(udfmp->s_table->entries[i].org);
1216 			if ((p_offset < udfmp->p_sectors) && (p_offset >= 0)) {
1217 				*sector =
1218 				   le32toh(udfmp->s_table->entries[i].map) +
1219 				    p_offset;
1220 				break;
1221 			}
1222 		}
1223 	}
1224 
1225 	return (0);
1226 }
1227