xref: /titanic_50/usr/src/uts/common/fs/hsfs/hsfs_vnops.c (revision ab4a9beb2e4d596be0b3288c7d92919e27781b57)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * Vnode operations for the High Sierra filesystem
30  */
31 
32 #include <sys/types.h>
33 #include <sys/t_lock.h>
34 #include <sys/param.h>
35 #include <sys/time.h>
36 #include <sys/systm.h>
37 #include <sys/sysmacros.h>
38 #include <sys/resource.h>
39 #include <sys/signal.h>
40 #include <sys/cred.h>
41 #include <sys/user.h>
42 #include <sys/buf.h>
43 #include <sys/vfs.h>
44 #include <sys/vfs_opreg.h>
45 #include <sys/stat.h>
46 #include <sys/vnode.h>
47 #include <sys/mode.h>
48 #include <sys/proc.h>
49 #include <sys/disp.h>
50 #include <sys/file.h>
51 #include <sys/fcntl.h>
52 #include <sys/flock.h>
53 #include <sys/kmem.h>
54 #include <sys/uio.h>
55 #include <sys/conf.h>
56 #include <sys/errno.h>
57 #include <sys/mman.h>
58 #include <sys/pathname.h>
59 #include <sys/debug.h>
60 #include <sys/vmsystm.h>
61 #include <sys/cmn_err.h>
62 #include <sys/fbuf.h>
63 #include <sys/dirent.h>
64 #include <sys/errno.h>
65 #include <sys/dkio.h>
66 #include <sys/cmn_err.h>
67 #include <sys/atomic.h>
68 
69 #include <vm/hat.h>
70 #include <vm/page.h>
71 #include <vm/pvn.h>
72 #include <vm/as.h>
73 #include <vm/seg.h>
74 #include <vm/seg_map.h>
75 #include <vm/seg_kmem.h>
76 #include <vm/seg_vn.h>
77 #include <vm/rm.h>
78 #include <vm/page.h>
79 #include <sys/swap.h>
80 #include <sys/avl.h>
81 #include <sys/sunldi.h>
82 #include <sys/ddi.h>
83 #include <sys/sunddi.h>
84 #include <sys/sdt.h>
85 
86 /*
87  * For struct modlinkage
88  */
89 #include <sys/modctl.h>
90 
91 #include <sys/fs/hsfs_spec.h>
92 #include <sys/fs/hsfs_node.h>
93 #include <sys/fs/hsfs_impl.h>
94 #include <sys/fs/hsfs_susp.h>
95 #include <sys/fs/hsfs_rrip.h>
96 
97 #include <fs/fs_subr.h>
98 
99 /* # of contiguous requests to detect sequential access pattern */
100 static int seq_contig_requests = 2;
101 
102 /*
103  * This is the max number os taskq threads that will be created
104  * if required. Since we are using a Dynamic TaskQ by default only
105  * one thread is created initially.
106  *
107  * NOTE: In the usual hsfs use case this per fs instance number
108  * of taskq threads should not place any undue load on a system.
109  * Even on an unusual system with say 100 CDROM drives, 800 threads
110  * will not be created unless all the drives are loaded and all
111  * of them are saturated with I/O at the same time! If there is at
112  * all a complaint of system load due to such an unusual case it
113  * should be easy enough to change to one per-machine Dynamic TaskQ
114  * for all hsfs mounts with a nthreads of say 32.
115  */
116 static int hsfs_taskq_nthreads = 8;	/* # of taskq threads per fs */
117 
118 /* Min count of adjacent bufs that will avoid buf coalescing */
119 static int hsched_coalesce_min = 2;
120 
121 /*
122  * Kmem caches for heavily used small allocations. Using these kmem
123  * caches provides a factor of 3 reduction in system time and greatly
124  * aids overall throughput esp. on SPARC.
125  */
126 struct kmem_cache *hio_cache;
127 struct kmem_cache *hio_info_cache;
128 
129 /*
130  * This tunable allows us to ignore inode numbers from rrip-1.12.
131  * In this case, we fall back to our default inode algorithm.
132  */
133 extern int use_rrip_inodes;
134 
135 /*
136  * Free behind logic from UFS to tame our thirst for
137  * the page cache.
138  * See usr/src/uts/common/fs/ufs/ufs_vnops.c for more
139  * explanation.
140  */
141 static int	freebehind = 1;
142 static int	smallfile = 0;
143 static int	cache_read_ahead = 0;
144 static u_offset_t smallfile64 = 32 * 1024;
145 #define	SMALLFILE1_D 1000
146 #define	SMALLFILE2_D 10
147 static u_offset_t smallfile1 = 32 * 1024;
148 static u_offset_t smallfile2 = 32 * 1024;
149 static clock_t smallfile_update = 0; /* when to recompute */
150 static uint_t smallfile1_d = SMALLFILE1_D;
151 static uint_t smallfile2_d = SMALLFILE2_D;
152 
153 static int hsched_deadline_compare(const void *x1, const void *x2);
154 static int hsched_offset_compare(const void *x1, const void *x2);
155 static void hsched_enqueue_io(struct hsfs *fsp, struct hio *hsio, int ra);
156 int hsched_invoke_strategy(struct hsfs *fsp);
157 
158 /* ARGSUSED */
159 static int
160 hsfs_fsync(vnode_t *cp, int syncflag, cred_t *cred)
161 {
162 	return (0);
163 }
164 
165 
166 /*ARGSUSED*/
167 static int
168 hsfs_read(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cred,
169 	struct caller_context *ct)
170 {
171 	caddr_t base;
172 	offset_t diff;
173 	int error;
174 	struct hsnode *hp;
175 	uint_t filesize;
176 	int dofree;
177 
178 	hp = VTOH(vp);
179 	/*
180 	 * if vp is of type VDIR, make sure dirent
181 	 * is filled up with all info (because of ptbl)
182 	 */
183 	if (vp->v_type == VDIR) {
184 		if (hp->hs_dirent.ext_size == 0)
185 			hs_filldirent(vp, &hp->hs_dirent);
186 	}
187 	filesize = hp->hs_dirent.ext_size;
188 
189 	/* Sanity checks. */
190 	if (uiop->uio_resid == 0 ||		/* No data wanted. */
191 	    uiop->uio_loffset > HS_MAXFILEOFF ||	/* Offset too big. */
192 	    uiop->uio_loffset >= filesize)	/* Past EOF. */
193 		return (0);
194 
195 	do {
196 		/*
197 		 * We want to ask for only the "right" amount of data.
198 		 * In this case that means:-
199 		 *
200 		 * We can't get data from beyond our EOF. If asked,
201 		 * we will give a short read.
202 		 *
203 		 * segmap_getmapflt returns buffers of MAXBSIZE bytes.
204 		 * These buffers are always MAXBSIZE aligned.
205 		 * If our starting offset is not MAXBSIZE aligned,
206 		 * we can only ask for less than MAXBSIZE bytes.
207 		 *
208 		 * If our requested offset and length are such that
209 		 * they belong in different MAXBSIZE aligned slots
210 		 * then we'll be making more than one call on
211 		 * segmap_getmapflt.
212 		 *
213 		 * This diagram shows the variables we use and their
214 		 * relationships.
215 		 *
216 		 * |<-----MAXBSIZE----->|
217 		 * +--------------------------...+
218 		 * |.....mapon->|<--n-->|....*...|EOF
219 		 * +--------------------------...+
220 		 * uio_loffset->|
221 		 * uio_resid....|<---------->|
222 		 * diff.........|<-------------->|
223 		 *
224 		 * So, in this case our offset is not aligned
225 		 * and our request takes us outside of the
226 		 * MAXBSIZE window. We will break this up into
227 		 * two segmap_getmapflt calls.
228 		 */
229 		size_t nbytes;
230 		offset_t mapon;
231 		size_t n;
232 		uint_t flags;
233 
234 		mapon = uiop->uio_loffset & MAXBOFFSET;
235 		diff = filesize - uiop->uio_loffset;
236 		nbytes = (size_t)MIN(MAXBSIZE - mapon, uiop->uio_resid);
237 		n = MIN(diff, nbytes);
238 		if (n <= 0) {
239 			/* EOF or request satisfied. */
240 			return (0);
241 		}
242 
243 		/*
244 		 * Freebehind computation taken from:
245 		 * usr/src/uts/common/fs/ufs/ufs_vnops.c
246 		 */
247 		if (drv_hztousec(ddi_get_lbolt()) >= smallfile_update) {
248 			uint64_t percpufreeb;
249 			if (smallfile1_d == 0) smallfile1_d = SMALLFILE1_D;
250 			if (smallfile2_d == 0) smallfile2_d = SMALLFILE2_D;
251 			percpufreeb = ptob((uint64_t)freemem) / ncpus_online;
252 			smallfile1 = percpufreeb / smallfile1_d;
253 			smallfile2 = percpufreeb / smallfile2_d;
254 			smallfile1 = MAX(smallfile1, smallfile);
255 			smallfile1 = MAX(smallfile1, smallfile64);
256 			smallfile2 = MAX(smallfile1, smallfile2);
257 			smallfile_update = drv_hztousec(ddi_get_lbolt())
258 			    + 1000000;
259 		}
260 
261 		dofree = freebehind &&
262 		    hp->hs_prev_offset == uiop->uio_loffset &&
263 		    hp->hs_ra_bytes > 0;
264 
265 		base = segmap_getmapflt(segkmap, vp,
266 		    (u_offset_t)uiop->uio_loffset, n, 1, S_READ);
267 
268 		error = uiomove(base + mapon, n, UIO_READ, uiop);
269 
270 		if (error == 0) {
271 			/*
272 			 * if read a whole block, or read to eof,
273 			 *  won't need this buffer again soon.
274 			 */
275 			if (n + mapon == MAXBSIZE ||
276 			    uiop->uio_loffset == filesize)
277 				flags = SM_DONTNEED;
278 			else
279 				flags = 0;
280 
281 			if (dofree) {
282 				flags = SM_FREE | SM_ASYNC;
283 				if ((cache_read_ahead == 0) &&
284 				    uiop->uio_loffset > smallfile2)
285 					flags |=  SM_DONTNEED;
286 			}
287 
288 			error = segmap_release(segkmap, base, flags);
289 		} else
290 			(void) segmap_release(segkmap, base, 0);
291 	} while (error == 0 && uiop->uio_resid > 0);
292 
293 	return (error);
294 }
295 
296 /*ARGSUSED2*/
297 static int
298 hsfs_getattr(
299 	struct vnode *vp,
300 	struct vattr *vap,
301 	int flags,
302 	struct cred *cred)
303 {
304 	struct hsnode *hp;
305 	struct vfs *vfsp;
306 	struct hsfs *fsp;
307 
308 	hp = VTOH(vp);
309 	fsp = VFS_TO_HSFS(vp->v_vfsp);
310 	vfsp = vp->v_vfsp;
311 
312 	if ((hp->hs_dirent.ext_size == 0) && (vp->v_type == VDIR)) {
313 		hs_filldirent(vp, &hp->hs_dirent);
314 	}
315 	vap->va_type = IFTOVT(hp->hs_dirent.mode);
316 	vap->va_mode = hp->hs_dirent.mode;
317 	vap->va_uid = hp->hs_dirent.uid;
318 	vap->va_gid = hp->hs_dirent.gid;
319 
320 	vap->va_fsid = vfsp->vfs_dev;
321 	vap->va_nodeid = (ino64_t)hp->hs_nodeid;
322 	vap->va_nlink = hp->hs_dirent.nlink;
323 	vap->va_size =	(offset_t)hp->hs_dirent.ext_size;
324 
325 	vap->va_atime.tv_sec = hp->hs_dirent.adate.tv_sec;
326 	vap->va_atime.tv_nsec = hp->hs_dirent.adate.tv_usec*1000;
327 	vap->va_mtime.tv_sec = hp->hs_dirent.mdate.tv_sec;
328 	vap->va_mtime.tv_nsec = hp->hs_dirent.mdate.tv_usec*1000;
329 	vap->va_ctime.tv_sec = hp->hs_dirent.cdate.tv_sec;
330 	vap->va_ctime.tv_nsec = hp->hs_dirent.cdate.tv_usec*1000;
331 	if (vp->v_type == VCHR || vp->v_type == VBLK)
332 		vap->va_rdev = hp->hs_dirent.r_dev;
333 	else
334 		vap->va_rdev = 0;
335 	vap->va_blksize = vfsp->vfs_bsize;
336 	/* no. of blocks = no. of data blocks + no. of xar blocks */
337 	vap->va_nblocks = (fsblkcnt64_t)howmany(vap->va_size + (u_longlong_t)
338 	    (hp->hs_dirent.xar_len << fsp->hsfs_vol.lbn_shift), DEV_BSIZE);
339 	vap->va_seq = hp->hs_seq;
340 	return (0);
341 }
342 
343 /*ARGSUSED*/
344 static int
345 hsfs_readlink(struct vnode *vp, struct uio *uiop, struct cred *cred)
346 {
347 	struct hsnode *hp;
348 
349 	if (vp->v_type != VLNK)
350 		return (EINVAL);
351 
352 	hp = VTOH(vp);
353 
354 	if (hp->hs_dirent.sym_link == (char *)NULL)
355 		return (ENOENT);
356 
357 	return (uiomove(hp->hs_dirent.sym_link,
358 	    (size_t)MIN(hp->hs_dirent.ext_size,
359 	    uiop->uio_resid), UIO_READ, uiop));
360 }
361 
362 /*ARGSUSED*/
363 static void
364 hsfs_inactive(struct vnode *vp, struct cred *cred)
365 {
366 	struct hsnode *hp;
367 	struct hsfs *fsp;
368 
369 	int nopage;
370 
371 	hp = VTOH(vp);
372 	fsp = VFS_TO_HSFS(vp->v_vfsp);
373 	/*
374 	 * Note: acquiring and holding v_lock for quite a while
375 	 * here serializes on the vnode; this is unfortunate, but
376 	 * likely not to overly impact performance, as the underlying
377 	 * device (CDROM drive) is quite slow.
378 	 */
379 	rw_enter(&fsp->hsfs_hash_lock, RW_WRITER);
380 	mutex_enter(&hp->hs_contents_lock);
381 	mutex_enter(&vp->v_lock);
382 
383 	if (vp->v_count < 1) {
384 		panic("hsfs_inactive: v_count < 1");
385 		/*NOTREACHED*/
386 	}
387 
388 	if (vp->v_count > 1 || (hp->hs_flags & HREF) == 0) {
389 		vp->v_count--;	/* release hold from vn_rele */
390 		mutex_exit(&vp->v_lock);
391 		mutex_exit(&hp->hs_contents_lock);
392 		rw_exit(&fsp->hsfs_hash_lock);
393 		return;
394 	}
395 	vp->v_count--;	/* release hold from vn_rele */
396 	if (vp->v_count == 0) {
397 		/*
398 		 * Free the hsnode.
399 		 * If there are no pages associated with the
400 		 * hsnode, give it back to the kmem_cache,
401 		 * else put at the end of this file system's
402 		 * internal free list.
403 		 */
404 		nopage = !vn_has_cached_data(vp);
405 		hp->hs_flags = 0;
406 		/*
407 		 * exit these locks now, since hs_freenode may
408 		 * kmem_free the hsnode and embedded vnode
409 		 */
410 		mutex_exit(&vp->v_lock);
411 		mutex_exit(&hp->hs_contents_lock);
412 		hs_freenode(vp, fsp, nopage);
413 	} else {
414 		mutex_exit(&vp->v_lock);
415 		mutex_exit(&hp->hs_contents_lock);
416 	}
417 	rw_exit(&fsp->hsfs_hash_lock);
418 }
419 
420 
421 /*ARGSUSED*/
422 static int
423 hsfs_lookup(
424 	struct vnode *dvp,
425 	char *nm,
426 	struct vnode **vpp,
427 	struct pathname *pnp,
428 	int flags,
429 	struct vnode *rdir,
430 	struct cred *cred)
431 {
432 	int error;
433 	int namelen = (int)strlen(nm);
434 
435 	if (*nm == '\0') {
436 		VN_HOLD(dvp);
437 		*vpp = dvp;
438 		return (0);
439 	}
440 
441 	/*
442 	 * If we're looking for ourself, life is simple.
443 	 */
444 	if (namelen == 1 && *nm == '.') {
445 		if (error = hs_access(dvp, (mode_t)VEXEC, cred))
446 			return (error);
447 		VN_HOLD(dvp);
448 		*vpp = dvp;
449 		return (0);
450 	}
451 
452 	return (hs_dirlook(dvp, nm, namelen, vpp, cred));
453 }
454 
455 
456 /*ARGSUSED*/
457 static int
458 hsfs_readdir(
459 	struct vnode	*vp,
460 	struct uio	*uiop,
461 	struct cred	*cred,
462 	int		*eofp)
463 {
464 	struct hsnode	*dhp;
465 	struct hsfs	*fsp;
466 	struct hs_direntry hd;
467 	struct dirent64	*nd;
468 	int		error;
469 	uint_t		offset;		/* real offset in directory */
470 	uint_t		dirsiz;		/* real size of directory */
471 	uchar_t		*blkp;
472 	int		hdlen;		/* length of hs directory entry */
473 	long		ndlen;		/* length of dirent entry */
474 	int		bytes_wanted;
475 	size_t		bufsize;	/* size of dirent buffer */
476 	char		*outbuf;	/* ptr to dirent buffer */
477 	char		*dname;
478 	int		dnamelen;
479 	size_t		dname_size;
480 	struct fbuf	*fbp;
481 	uint_t		last_offset;	/* last index into current dir block */
482 	ino64_t		dirino;	/* temporary storage before storing in dirent */
483 	off_t		diroff;
484 
485 	dhp = VTOH(vp);
486 	fsp = VFS_TO_HSFS(vp->v_vfsp);
487 	if (dhp->hs_dirent.ext_size == 0)
488 		hs_filldirent(vp, &dhp->hs_dirent);
489 	dirsiz = dhp->hs_dirent.ext_size;
490 	if (uiop->uio_loffset >= dirsiz) {	/* at or beyond EOF */
491 		if (eofp)
492 			*eofp = 1;
493 		return (0);
494 	}
495 	ASSERT(uiop->uio_loffset <= HS_MAXFILEOFF);
496 	offset = uiop->uio_loffset;
497 
498 	dname_size = fsp->hsfs_namemax + 1;	/* 1 for the ending NUL */
499 	dname = kmem_alloc(dname_size, KM_SLEEP);
500 	bufsize = uiop->uio_resid + sizeof (struct dirent64);
501 
502 	outbuf = kmem_alloc(bufsize, KM_SLEEP);
503 	nd = (struct dirent64 *)outbuf;
504 
505 	while (offset < dirsiz) {
506 		bytes_wanted = MIN(MAXBSIZE, dirsiz - (offset & MAXBMASK));
507 
508 		error = fbread(vp, (offset_t)(offset & MAXBMASK),
509 		    (unsigned int)bytes_wanted, S_READ, &fbp);
510 		if (error)
511 			goto done;
512 
513 		blkp = (uchar_t *)fbp->fb_addr;
514 		last_offset = (offset & MAXBMASK) + fbp->fb_count;
515 
516 #define	rel_offset(offset) ((offset) & MAXBOFFSET)	/* index into blkp */
517 
518 		while (offset < last_offset) {
519 			/*
520 			 * Very similar validation code is found in
521 			 * process_dirblock(), hsfs_node.c.
522 			 * For an explanation, see there.
523 			 * It may make sense for the future to
524 			 * "consolidate" the code in hs_parsedir(),
525 			 * process_dirblock() and hsfs_readdir() into
526 			 * a single utility function.
527 			 */
528 			hdlen = (int)((uchar_t)
529 			    HDE_DIR_LEN(&blkp[rel_offset(offset)]));
530 			if (hdlen < HDE_ROOT_DIR_REC_SIZE ||
531 			    offset + hdlen > last_offset) {
532 				/*
533 				 * advance to next sector boundary
534 				 */
535 				offset = roundup(offset + 1, HS_SECTOR_SIZE);
536 				if (hdlen)
537 					hs_log_bogus_disk_warning(fsp,
538 					    HSFS_ERR_TRAILING_JUNK, 0);
539 
540 				continue;
541 			}
542 
543 			bzero(&hd, sizeof (hd));
544 
545 			/*
546 			 * Just ignore invalid directory entries.
547 			 * XXX - maybe hs_parsedir() will detect EXISTENCE bit
548 			 */
549 			if (!hs_parsedir(fsp, &blkp[rel_offset(offset)],
550 			    &hd, dname, &dnamelen, last_offset - offset)) {
551 				/*
552 				 * Determine if there is enough room
553 				 */
554 				ndlen = (long)DIRENT64_RECLEN((dnamelen));
555 
556 				if ((ndlen + ((char *)nd - outbuf)) >
557 				    uiop->uio_resid) {
558 					fbrelse(fbp, S_READ);
559 					goto done; /* output buffer full */
560 				}
561 
562 				diroff = offset + hdlen;
563 				/*
564 				 * If the media carries rrip-v1.12 or newer,
565 				 * and we trust the inodes from the rrip data
566 				 * (use_rrip_inodes != 0), use that data. If the
567 				 * media has been created by a recent mkisofs
568 				 * version, we may trust all numbers in the
569 				 * starting extent number; otherwise, we cannot
570 				 * do this for zero sized files and symlinks,
571 				 * because if we did we'd end up mapping all of
572 				 * them to the same node. We use HS_DUMMY_INO
573 				 * in this case and make sure that we will not
574 				 * map all files to the same meta data.
575 				 */
576 				if (hd.inode != 0 && use_rrip_inodes) {
577 					dirino = hd.inode;
578 				} else if ((hd.ext_size == 0 ||
579 				    hd.sym_link != (char *)NULL) &&
580 				    (fsp->hsfs_flags & HSFSMNT_INODE) == 0) {
581 					dirino = HS_DUMMY_INO;
582 				} else {
583 					dirino = hd.ext_lbn;
584 				}
585 
586 				/* strncpy(9f) will zero uninitialized bytes */
587 
588 				ASSERT(strlen(dname) + 1 <=
589 				    DIRENT64_NAMELEN(ndlen));
590 				(void) strncpy(nd->d_name, dname,
591 				    DIRENT64_NAMELEN(ndlen));
592 				nd->d_reclen = (ushort_t)ndlen;
593 				nd->d_off = (offset_t)diroff;
594 				nd->d_ino = dirino;
595 				nd = (struct dirent64 *)((char *)nd + ndlen);
596 
597 				/*
598 				 * free up space allocated for symlink
599 				 */
600 				if (hd.sym_link != (char *)NULL) {
601 					kmem_free(hd.sym_link,
602 					    (size_t)(hd.ext_size+1));
603 					hd.sym_link = (char *)NULL;
604 				}
605 			}
606 			offset += hdlen;
607 		}
608 		fbrelse(fbp, S_READ);
609 	}
610 
611 	/*
612 	 * Got here for one of the following reasons:
613 	 *	1) outbuf is full (error == 0)
614 	 *	2) end of directory reached (error == 0)
615 	 *	3) error reading directory sector (error != 0)
616 	 *	4) directory entry crosses sector boundary (error == 0)
617 	 *
618 	 * If any directory entries have been copied, don't report
619 	 * case 4.  Instead, return the valid directory entries.
620 	 *
621 	 * If no entries have been copied, report the error.
622 	 * If case 4, this will be indistiguishable from EOF.
623 	 */
624 done:
625 	ndlen = ((char *)nd - outbuf);
626 	if (ndlen != 0) {
627 		error = uiomove(outbuf, (size_t)ndlen, UIO_READ, uiop);
628 		uiop->uio_loffset = offset;
629 	}
630 	kmem_free(dname, dname_size);
631 	kmem_free(outbuf, bufsize);
632 	if (eofp && error == 0)
633 		*eofp = (uiop->uio_loffset >= dirsiz);
634 	return (error);
635 }
636 
637 static int
638 hsfs_fid(struct vnode *vp, struct fid *fidp)
639 {
640 	struct hsnode *hp;
641 	struct hsfid *fid;
642 
643 	if (fidp->fid_len < (sizeof (*fid) - sizeof (fid->hf_len))) {
644 		fidp->fid_len = sizeof (*fid) - sizeof (fid->hf_len);
645 		return (ENOSPC);
646 	}
647 
648 	fid = (struct hsfid *)fidp;
649 	fid->hf_len = sizeof (*fid) - sizeof (fid->hf_len);
650 	hp = VTOH(vp);
651 	mutex_enter(&hp->hs_contents_lock);
652 	fid->hf_dir_lbn = hp->hs_dir_lbn;
653 	fid->hf_dir_off = (ushort_t)hp->hs_dir_off;
654 	fid->hf_ino = hp->hs_nodeid;
655 	mutex_exit(&hp->hs_contents_lock);
656 	return (0);
657 }
658 
659 /*ARGSUSED*/
660 static int
661 hsfs_open(struct vnode **vpp, int flag, struct cred *cred)
662 {
663 	return (0);
664 }
665 
666 /*ARGSUSED*/
667 static int
668 hsfs_close(
669 	struct vnode *vp,
670 	int flag,
671 	int count,
672 	offset_t offset,
673 	struct cred *cred)
674 {
675 	(void) cleanlocks(vp, ttoproc(curthread)->p_pid, 0);
676 	cleanshares(vp, ttoproc(curthread)->p_pid);
677 	return (0);
678 }
679 
680 /*ARGSUSED2*/
681 static int
682 hsfs_access(struct vnode *vp, int mode, int flags, cred_t *cred)
683 {
684 	return (hs_access(vp, (mode_t)mode, cred));
685 }
686 
687 /*
688  * the seek time of a CD-ROM is very slow, and data transfer
689  * rate is even worse (max. 150K per sec).  The design
690  * decision is to reduce access to cd-rom as much as possible,
691  * and to transfer a sizable block (read-ahead) of data at a time.
692  * UFS style of read ahead one block at a time is not appropriate,
693  * and is not supported
694  */
695 
696 /*
697  * KLUSTSIZE should be a multiple of PAGESIZE and <= MAXPHYS.
698  */
699 #define	KLUSTSIZE	(56 * 1024)
700 /* we don't support read ahead */
701 int hsfs_lostpage;	/* no. of times we lost original page */
702 
703 /*
704  * Used to prevent biodone() from releasing buf resources that
705  * we didn't allocate in quite the usual way.
706  */
707 /*ARGSUSED*/
708 int
709 hsfs_iodone(struct buf *bp)
710 {
711 	sema_v(&bp->b_io);
712 	return (0);
713 }
714 
715 /*
716  * The taskq thread that invokes the scheduling function to ensure
717  * that all readaheads are complete and cleans up the associated
718  * memory and releases the page lock.
719  */
720 void
721 hsfs_ra_task(void *arg)
722 {
723 	struct hio_info *info = arg;
724 	uint_t count;
725 	struct buf *wbuf;
726 
727 	ASSERT(info->pp != NULL);
728 
729 	for (count = 0; count < info->bufsused; count++) {
730 		wbuf = &(info->bufs[count]);
731 
732 		DTRACE_PROBE1(hsfs_io_wait_ra, struct buf *, wbuf);
733 		while (sema_tryp(&(info->sema[count])) == 0) {
734 			if (hsched_invoke_strategy(info->fsp)) {
735 				sema_p(&(info->sema[count]));
736 				break;
737 			}
738 		}
739 		sema_destroy(&(info->sema[count]));
740 		DTRACE_PROBE1(hsfs_io_done_ra, struct buf *, wbuf);
741 		biofini(&(info->bufs[count]));
742 	}
743 	for (count = 0; count < info->bufsused; count++) {
744 		if (info->vas[count] != NULL) {
745 			ppmapout(info->vas[count]);
746 		}
747 	}
748 	kmem_free(info->vas, info->bufcnt * sizeof (caddr_t));
749 	kmem_free(info->bufs, info->bufcnt * sizeof (struct buf));
750 	kmem_free(info->sema, info->bufcnt * sizeof (ksema_t));
751 
752 	pvn_read_done(info->pp, 0);
753 	kmem_cache_free(hio_info_cache, info);
754 }
755 
756 /*
757  * Submit asynchronous readahead requests to the I/O scheduler
758  * depending on the number of pages to read ahead. These requests
759  * are asynchronous to the calling thread but I/O requests issued
760  * subsequently by other threads with higher LBNs must wait for
761  * these readaheads to complete since we have a single ordered
762  * I/O pipeline. Thus these readaheads are semi-asynchronous.
763  * A TaskQ handles waiting for the readaheads to complete.
764  *
765  * This function is mostly a copy of hsfs_getapage but somewhat
766  * simpler. A readahead request is aborted if page allocation
767  * fails.
768  */
769 /*ARGSUSED*/
770 static int
771 hsfs_getpage_ra(
772 	struct vnode *vp,
773 	u_offset_t off,
774 	struct seg *seg,
775 	caddr_t addr,
776 	struct hsnode *hp,
777 	struct hsfs *fsp,
778 	int	xarsiz,
779 	offset_t	bof,
780 	int	chunk_lbn_count,
781 	int	chunk_data_bytes)
782 {
783 	struct buf *bufs;
784 	caddr_t *vas;
785 	caddr_t va;
786 	struct page *pp, *searchp, *lastp;
787 	struct vnode *devvp;
788 	ulong_t	byte_offset;
789 	size_t	io_len_tmp;
790 	uint_t	io_off, io_len;
791 	uint_t	xlen;
792 	uint_t	filsiz;
793 	uint_t	secsize;
794 	uint_t	bufcnt;
795 	uint_t	bufsused;
796 	uint_t	count;
797 	uint_t	io_end;
798 	uint_t	which_chunk_lbn;
799 	uint_t	offset_lbn;
800 	uint_t	offset_extra;
801 	offset_t	offset_bytes;
802 	uint_t	remaining_bytes;
803 	uint_t	extension;
804 	int	remainder;	/* must be signed */
805 	diskaddr_t driver_block;
806 	u_offset_t io_off_tmp;
807 	ksema_t	*fio_done;
808 	struct hio_info *info;
809 	size_t len;
810 
811 	ASSERT(fsp->hqueue != NULL);
812 
813 	if (addr >= seg->s_base + seg->s_size) {
814 		return (-1);
815 	}
816 
817 	devvp = fsp->hsfs_devvp;
818 	secsize = fsp->hsfs_vol.lbn_size;  /* bytes per logical block */
819 
820 	/* file data size */
821 	filsiz = hp->hs_dirent.ext_size;
822 
823 	if (off >= filsiz)
824 		return (0);
825 
826 	extension = 0;
827 	pp = NULL;
828 
829 	extension += hp->hs_ra_bytes;
830 
831 	/*
832 	 * Some cd writers don't write sectors that aren't used.  Also,
833 	 * there's no point in reading sectors we'll never look at.  So,
834 	 * if we're asked to go beyond the end of a file, truncate to the
835 	 * length of that file.
836 	 *
837 	 * Additionally, this behaviour is required by section 6.4.5 of
838 	 * ISO 9660:1988(E).
839 	 */
840 	len = MIN(extension ? extension : PAGESIZE, filsiz - off);
841 
842 	/* A little paranoia */
843 	if (len <= 0)
844 		return (-1);
845 
846 	/*
847 	 * After all that, make sure we're asking for things in units
848 	 * that bdev_strategy() will understand (see bug 4202551).
849 	 */
850 	len = roundup(len, DEV_BSIZE);
851 
852 	pp = pvn_read_kluster(vp, off, seg, addr, &io_off_tmp,
853 	    &io_len_tmp, off, len, 1);
854 
855 	if (pp == NULL) {
856 		hp->hs_num_contig = 0;
857 		hp->hs_ra_bytes = 0;
858 		hp->hs_prev_offset = 0;
859 		return (-1);
860 	}
861 
862 	io_off = (uint_t)io_off_tmp;
863 	io_len = (uint_t)io_len_tmp;
864 
865 	/* check for truncation */
866 	/*
867 	 * xxx Clean up and return EIO instead?
868 	 * xxx Ought to go to u_offset_t for everything, but we
869 	 * xxx call lots of things that want uint_t arguments.
870 	 */
871 	ASSERT(io_off == io_off_tmp);
872 
873 	/*
874 	 * get enough buffers for worst-case scenario
875 	 * (i.e., no coalescing possible).
876 	 */
877 	bufcnt = (len + secsize - 1) / secsize;
878 	bufs = kmem_alloc(bufcnt * sizeof (struct buf), KM_SLEEP);
879 	vas = kmem_alloc(bufcnt * sizeof (caddr_t), KM_SLEEP);
880 
881 	/*
882 	 * Allocate a array of semaphores since we are doing I/O
883 	 * scheduling.
884 	 */
885 	fio_done = kmem_alloc(bufcnt * sizeof (ksema_t), KM_SLEEP);
886 
887 	/*
888 	 * If our filesize is not an integer multiple of PAGESIZE,
889 	 * we zero that part of the last page that's between EOF and
890 	 * the PAGESIZE boundary.
891 	 */
892 	xlen = io_len & PAGEOFFSET;
893 	if (xlen != 0)
894 		pagezero(pp->p_prev, xlen, PAGESIZE - xlen);
895 
896 	DTRACE_PROBE2(hsfs_readahead, struct vnode *, vp, uint_t, io_len);
897 
898 	va = NULL;
899 	lastp = NULL;
900 	searchp = pp;
901 	io_end = io_off + io_len;
902 	for (count = 0, byte_offset = io_off;
903 	    byte_offset < io_end;
904 	    count++) {
905 		ASSERT(count < bufcnt);
906 
907 		bioinit(&bufs[count]);
908 		bufs[count].b_edev = devvp->v_rdev;
909 		bufs[count].b_dev = cmpdev(devvp->v_rdev);
910 		bufs[count].b_flags = B_NOCACHE|B_BUSY|B_READ;
911 		bufs[count].b_iodone = hsfs_iodone;
912 		bufs[count].b_vp = vp;
913 		bufs[count].b_file = vp;
914 
915 		/* Compute disk address for interleaving. */
916 
917 		/* considered without skips */
918 		which_chunk_lbn = byte_offset / chunk_data_bytes;
919 
920 		/* factor in skips */
921 		offset_lbn = which_chunk_lbn * chunk_lbn_count;
922 
923 		/* convert to physical byte offset for lbn */
924 		offset_bytes = LBN_TO_BYTE(offset_lbn, vp->v_vfsp);
925 
926 		/* don't forget offset into lbn */
927 		offset_extra = byte_offset % chunk_data_bytes;
928 
929 		/* get virtual block number for driver */
930 		driver_block = lbtodb(bof + xarsiz
931 		    + offset_bytes + offset_extra);
932 
933 		if (lastp != searchp) {
934 			/* this branch taken first time through loop */
935 			va = vas[count] = ppmapin(searchp, PROT_WRITE,
936 			    (caddr_t)-1);
937 			/* ppmapin() guarantees not to return NULL */
938 		} else {
939 			vas[count] = NULL;
940 		}
941 
942 		bufs[count].b_un.b_addr = va + byte_offset % PAGESIZE;
943 		bufs[count].b_offset =
944 		    (offset_t)(byte_offset - io_off + off);
945 
946 		/*
947 		 * We specifically use the b_lblkno member here
948 		 * as even in the 32 bit world driver_block can
949 		 * get very large in line with the ISO9660 spec.
950 		 */
951 
952 		bufs[count].b_lblkno = driver_block;
953 
954 		remaining_bytes = ((which_chunk_lbn + 1) * chunk_data_bytes)
955 		    - byte_offset;
956 
957 		/*
958 		 * remaining_bytes can't be zero, as we derived
959 		 * which_chunk_lbn directly from byte_offset.
960 		 */
961 		if ((remaining_bytes + byte_offset) < (off + len)) {
962 			/* coalesce-read the rest of the chunk */
963 			bufs[count].b_bcount = remaining_bytes;
964 		} else {
965 			/* get the final bits */
966 			bufs[count].b_bcount = off + len - byte_offset;
967 		}
968 
969 		remainder = PAGESIZE - (byte_offset % PAGESIZE);
970 		if (bufs[count].b_bcount > remainder) {
971 			bufs[count].b_bcount = remainder;
972 		}
973 
974 		bufs[count].b_bufsize = bufs[count].b_bcount;
975 		if (((offset_t)byte_offset + bufs[count].b_bcount) >
976 		    HS_MAXFILEOFF) {
977 			break;
978 		}
979 		byte_offset += bufs[count].b_bcount;
980 
981 		/*
982 		 * We are scheduling I/O so we need to enqueue
983 		 * requests rather than calling bdev_strategy
984 		 * here. A later invocation of the scheduling
985 		 * function will take care of doing the actual
986 		 * I/O as it selects requests from the queue as
987 		 * per the scheduling logic.
988 		 */
989 		struct hio *hsio = kmem_cache_alloc(hio_cache,
990 		    KM_SLEEP);
991 
992 		sema_init(&fio_done[count], 0, NULL,
993 		    SEMA_DEFAULT, NULL);
994 		hsio->bp = &bufs[count];
995 		hsio->sema = &fio_done[count];
996 		hsio->io_lblkno = bufs[count].b_lblkno;
997 		hsio->nblocks = howmany(hsio->bp->b_bcount,
998 		    DEV_BSIZE);
999 
1000 		/* used for deadline */
1001 		hsio->io_timestamp = drv_hztousec(ddi_get_lbolt());
1002 
1003 		/* for I/O coalescing */
1004 		hsio->contig_chain = NULL;
1005 		hsched_enqueue_io(fsp, hsio, 1);
1006 
1007 		lwp_stat_update(LWP_STAT_INBLK, 1);
1008 		lastp = searchp;
1009 		if ((remainder - bufs[count].b_bcount) < 1) {
1010 			searchp = searchp->p_next;
1011 		}
1012 	}
1013 
1014 	bufsused = count;
1015 	info = kmem_cache_alloc(hio_info_cache, KM_SLEEP);
1016 	info->bufs = bufs;
1017 	info->vas = vas;
1018 	info->sema = fio_done;
1019 	info->bufsused = bufsused;
1020 	info->bufcnt = bufcnt;
1021 	info->fsp = fsp;
1022 	info->pp = pp;
1023 
1024 	(void) taskq_dispatch(fsp->hqueue->ra_task,
1025 	    hsfs_ra_task, info, KM_SLEEP);
1026 	/*
1027 	 * The I/O locked pages are unlocked in our taskq thread.
1028 	 */
1029 	return (0);
1030 }
1031 
1032 /*
1033  * Each file may have a different interleaving on disk.  This makes
1034  * things somewhat interesting.  The gist is that there are some
1035  * number of contiguous data sectors, followed by some other number
1036  * of contiguous skip sectors.  The sum of those two sets of sectors
1037  * defines the interleave size.  Unfortunately, it means that we generally
1038  * can't simply read N sectors starting at a given offset to satisfy
1039  * any given request.
1040  *
1041  * What we do is get the relevant memory pages via pvn_read_kluster(),
1042  * then stride through the interleaves, setting up a buf for each
1043  * sector that needs to be brought in.  Instead of kmem_alloc'ing
1044  * space for the sectors, though, we just point at the appropriate
1045  * spot in the relevant page for each of them.  This saves us a bunch
1046  * of copying.
1047  *
1048  * NOTICE: The code below in hsfs_getapage is mostly same as the code
1049  *         in hsfs_getpage_ra above (with some omissions). If you are
1050  *         making any change to this function, please also look at
1051  *         hsfs_getpage_ra.
1052  */
1053 /*ARGSUSED*/
1054 static int
1055 hsfs_getapage(
1056 	struct vnode *vp,
1057 	u_offset_t off,
1058 	size_t len,
1059 	uint_t *protp,
1060 	struct page *pl[],
1061 	size_t plsz,
1062 	struct seg *seg,
1063 	caddr_t addr,
1064 	enum seg_rw rw,
1065 	struct cred *cred)
1066 {
1067 	struct hsnode *hp;
1068 	struct hsfs *fsp;
1069 	int	err;
1070 	struct buf *bufs;
1071 	caddr_t *vas;
1072 	caddr_t va;
1073 	struct page *pp, *searchp, *lastp;
1074 	page_t	*pagefound;
1075 	offset_t	bof;
1076 	struct vnode *devvp;
1077 	ulong_t	byte_offset;
1078 	size_t	io_len_tmp;
1079 	uint_t	io_off, io_len;
1080 	uint_t	xlen;
1081 	uint_t	filsiz;
1082 	uint_t	secsize;
1083 	uint_t	bufcnt;
1084 	uint_t	bufsused;
1085 	uint_t	count;
1086 	uint_t	io_end;
1087 	uint_t	which_chunk_lbn;
1088 	uint_t	offset_lbn;
1089 	uint_t	offset_extra;
1090 	offset_t	offset_bytes;
1091 	uint_t	remaining_bytes;
1092 	uint_t	extension;
1093 	int	remainder;	/* must be signed */
1094 	int	chunk_lbn_count;
1095 	int	chunk_data_bytes;
1096 	int	xarsiz;
1097 	diskaddr_t driver_block;
1098 	u_offset_t io_off_tmp;
1099 	ksema_t *fio_done;
1100 	int	calcdone;
1101 
1102 	/*
1103 	 * We don't support asynchronous operation at the moment, so
1104 	 * just pretend we did it.  If the pages are ever actually
1105 	 * needed, they'll get brought in then.
1106 	 */
1107 	if (pl == NULL)
1108 		return (0);
1109 
1110 	hp = VTOH(vp);
1111 	fsp = VFS_TO_HSFS(vp->v_vfsp);
1112 	devvp = fsp->hsfs_devvp;
1113 	secsize = fsp->hsfs_vol.lbn_size;  /* bytes per logical block */
1114 
1115 	/* file data size */
1116 	filsiz = hp->hs_dirent.ext_size;
1117 
1118 	/* disk addr for start of file */
1119 	bof = LBN_TO_BYTE((offset_t)hp->hs_dirent.ext_lbn, vp->v_vfsp);
1120 
1121 	/* xarsiz byte must be skipped for data */
1122 	xarsiz = hp->hs_dirent.xar_len << fsp->hsfs_vol.lbn_shift;
1123 
1124 	/* how many logical blocks in an interleave (data+skip) */
1125 	chunk_lbn_count = hp->hs_dirent.intlf_sz + hp->hs_dirent.intlf_sk;
1126 
1127 	if (chunk_lbn_count == 0) {
1128 		chunk_lbn_count = 1;
1129 	}
1130 
1131 	/*
1132 	 * Convert interleaving size into bytes.  The zero case
1133 	 * (no interleaving) optimization is handled as a side-
1134 	 * effect of the read-ahead logic.
1135 	 */
1136 	if (hp->hs_dirent.intlf_sz == 0) {
1137 		chunk_data_bytes = LBN_TO_BYTE(1, vp->v_vfsp);
1138 		/*
1139 		 * Optimization: If our pagesize is a multiple of LBN
1140 		 * bytes, we can avoid breaking up a page into individual
1141 		 * lbn-sized requests.
1142 		 */
1143 		if (PAGESIZE % chunk_data_bytes == 0) {
1144 			chunk_lbn_count = BYTE_TO_LBN(PAGESIZE, vp->v_vfsp);
1145 			chunk_data_bytes = PAGESIZE;
1146 		}
1147 	} else {
1148 		chunk_data_bytes =
1149 		    LBN_TO_BYTE(hp->hs_dirent.intlf_sz, vp->v_vfsp);
1150 	}
1151 
1152 reread:
1153 	err = 0;
1154 	pagefound = 0;
1155 	calcdone = 0;
1156 
1157 	/*
1158 	 * Do some read-ahead.  This mostly saves us a bit of
1159 	 * system cpu time more than anything else when doing
1160 	 * sequential reads.  At some point, could do the
1161 	 * read-ahead asynchronously which might gain us something
1162 	 * on wall time, but it seems unlikely....
1163 	 *
1164 	 * We do the easy case here, which is to read through
1165 	 * the end of the chunk, minus whatever's at the end that
1166 	 * won't exactly fill a page.
1167 	 */
1168 	if (hp->hs_ra_bytes > 0 && chunk_data_bytes != PAGESIZE) {
1169 		which_chunk_lbn = (off + len) / chunk_data_bytes;
1170 		extension = ((which_chunk_lbn + 1) * chunk_data_bytes) - off;
1171 		extension -= (extension % PAGESIZE);
1172 	} else {
1173 		extension = roundup(len, PAGESIZE);
1174 	}
1175 
1176 	atomic_inc_64(&fsp->total_pages_requested);
1177 
1178 	pp = NULL;
1179 again:
1180 	/* search for page in buffer */
1181 	if ((pagefound = page_exists(vp, off)) == 0) {
1182 		/*
1183 		 * Need to really do disk IO to get the page.
1184 		 */
1185 		if (!calcdone) {
1186 			extension += hp->hs_ra_bytes;
1187 
1188 			/*
1189 			 * Some cd writers don't write sectors that aren't
1190 			 * used. Also, there's no point in reading sectors
1191 			 * we'll never look at.  So, if we're asked to go
1192 			 * beyond the end of a file, truncate to the length
1193 			 * of that file.
1194 			 *
1195 			 * Additionally, this behaviour is required by section
1196 			 * 6.4.5 of ISO 9660:1988(E).
1197 			 */
1198 			len = MIN(extension ? extension : PAGESIZE,
1199 			    filsiz - off);
1200 
1201 			/* A little paranoia. */
1202 			ASSERT(len > 0);
1203 
1204 			/*
1205 			 * After all that, make sure we're asking for things
1206 			 * in units that bdev_strategy() will understand
1207 			 * (see bug 4202551).
1208 			 */
1209 			len = roundup(len, DEV_BSIZE);
1210 			calcdone = 1;
1211 		}
1212 
1213 		pp = pvn_read_kluster(vp, off, seg, addr, &io_off_tmp,
1214 		    &io_len_tmp, off, len, 0);
1215 
1216 		if (pp == NULL) {
1217 			/*
1218 			 * Pressure on memory, roll back readahead
1219 			 */
1220 			hp->hs_num_contig = 0;
1221 			hp->hs_ra_bytes = 0;
1222 			hp->hs_prev_offset = 0;
1223 			goto again;
1224 		}
1225 
1226 		io_off = (uint_t)io_off_tmp;
1227 		io_len = (uint_t)io_len_tmp;
1228 
1229 		/* check for truncation */
1230 		/*
1231 		 * xxx Clean up and return EIO instead?
1232 		 * xxx Ought to go to u_offset_t for everything, but we
1233 		 * xxx call lots of things that want uint_t arguments.
1234 		 */
1235 		ASSERT(io_off == io_off_tmp);
1236 
1237 		/*
1238 		 * get enough buffers for worst-case scenario
1239 		 * (i.e., no coalescing possible).
1240 		 */
1241 		bufcnt = (len + secsize - 1) / secsize;
1242 		bufs = kmem_zalloc(bufcnt * sizeof (struct buf), KM_SLEEP);
1243 		vas = kmem_alloc(bufcnt * sizeof (caddr_t), KM_SLEEP);
1244 
1245 		/*
1246 		 * Allocate a array of semaphores if we are doing I/O
1247 		 * scheduling.
1248 		 */
1249 		if (fsp->hqueue != NULL)
1250 			fio_done = kmem_alloc(bufcnt * sizeof (ksema_t),
1251 			    KM_SLEEP);
1252 		for (count = 0; count < bufcnt; count++) {
1253 			bioinit(&bufs[count]);
1254 			bufs[count].b_edev = devvp->v_rdev;
1255 			bufs[count].b_dev = cmpdev(devvp->v_rdev);
1256 			bufs[count].b_flags = B_NOCACHE|B_BUSY|B_READ;
1257 			bufs[count].b_iodone = hsfs_iodone;
1258 			bufs[count].b_vp = vp;
1259 			bufs[count].b_file = vp;
1260 		}
1261 
1262 		/*
1263 		 * If our filesize is not an integer multiple of PAGESIZE,
1264 		 * we zero that part of the last page that's between EOF and
1265 		 * the PAGESIZE boundary.
1266 		 */
1267 		xlen = io_len & PAGEOFFSET;
1268 		if (xlen != 0)
1269 			pagezero(pp->p_prev, xlen, PAGESIZE - xlen);
1270 
1271 		va = NULL;
1272 		lastp = NULL;
1273 		searchp = pp;
1274 		io_end = io_off + io_len;
1275 		for (count = 0, byte_offset = io_off;
1276 		    byte_offset < io_end; count++) {
1277 			ASSERT(count < bufcnt);
1278 
1279 			/* Compute disk address for interleaving. */
1280 
1281 			/* considered without skips */
1282 			which_chunk_lbn = byte_offset / chunk_data_bytes;
1283 
1284 			/* factor in skips */
1285 			offset_lbn = which_chunk_lbn * chunk_lbn_count;
1286 
1287 			/* convert to physical byte offset for lbn */
1288 			offset_bytes = LBN_TO_BYTE(offset_lbn, vp->v_vfsp);
1289 
1290 			/* don't forget offset into lbn */
1291 			offset_extra = byte_offset % chunk_data_bytes;
1292 
1293 			/* get virtual block number for driver */
1294 			driver_block =
1295 			    lbtodb(bof + xarsiz + offset_bytes + offset_extra);
1296 
1297 			if (lastp != searchp) {
1298 				/* this branch taken first time through loop */
1299 				va = vas[count] =
1300 				    ppmapin(searchp, PROT_WRITE, (caddr_t)-1);
1301 				/* ppmapin() guarantees not to return NULL */
1302 			} else {
1303 				vas[count] = NULL;
1304 			}
1305 
1306 			bufs[count].b_un.b_addr = va + byte_offset % PAGESIZE;
1307 			bufs[count].b_offset =
1308 			    (offset_t)(byte_offset - io_off + off);
1309 
1310 			/*
1311 			 * We specifically use the b_lblkno member here
1312 			 * as even in the 32 bit world driver_block can
1313 			 * get very large in line with the ISO9660 spec.
1314 			 */
1315 
1316 			bufs[count].b_lblkno = driver_block;
1317 
1318 			remaining_bytes =
1319 			    ((which_chunk_lbn + 1) * chunk_data_bytes)
1320 			    - byte_offset;
1321 
1322 			/*
1323 			 * remaining_bytes can't be zero, as we derived
1324 			 * which_chunk_lbn directly from byte_offset.
1325 			 */
1326 			if ((remaining_bytes + byte_offset) < (off + len)) {
1327 				/* coalesce-read the rest of the chunk */
1328 				bufs[count].b_bcount = remaining_bytes;
1329 			} else {
1330 				/* get the final bits */
1331 				bufs[count].b_bcount = off + len - byte_offset;
1332 			}
1333 
1334 			/*
1335 			 * It would be nice to do multiple pages'
1336 			 * worth at once here when the opportunity
1337 			 * arises, as that has been shown to improve
1338 			 * our wall time.  However, to do that
1339 			 * requires that we use the pageio subsystem,
1340 			 * which doesn't mix well with what we're
1341 			 * already using here.  We can't use pageio
1342 			 * all the time, because that subsystem
1343 			 * assumes that a page is stored in N
1344 			 * contiguous blocks on the device.
1345 			 * Interleaving violates that assumption.
1346 			 *
1347 			 * Update: This is now not so big a problem
1348 			 * because of the I/O scheduler sitting below
1349 			 * that can re-order and coalesce I/O requests.
1350 			 */
1351 
1352 			remainder = PAGESIZE - (byte_offset % PAGESIZE);
1353 			if (bufs[count].b_bcount > remainder) {
1354 				bufs[count].b_bcount = remainder;
1355 			}
1356 
1357 			bufs[count].b_bufsize = bufs[count].b_bcount;
1358 			if (((offset_t)byte_offset + bufs[count].b_bcount) >
1359 			    HS_MAXFILEOFF) {
1360 				break;
1361 			}
1362 			byte_offset += bufs[count].b_bcount;
1363 
1364 			if (fsp->hqueue == NULL) {
1365 				(void) bdev_strategy(&bufs[count]);
1366 
1367 			} else {
1368 				/*
1369 				 * We are scheduling I/O so we need to enqueue
1370 				 * requests rather than calling bdev_strategy
1371 				 * here. A later invocation of the scheduling
1372 				 * function will take care of doing the actual
1373 				 * I/O as it selects requests from the queue as
1374 				 * per the scheduling logic.
1375 				 */
1376 				struct hio *hsio = kmem_cache_alloc(hio_cache,
1377 				    KM_SLEEP);
1378 
1379 				sema_init(&fio_done[count], 0, NULL,
1380 				    SEMA_DEFAULT, NULL);
1381 				hsio->bp = &bufs[count];
1382 				hsio->sema = &fio_done[count];
1383 				hsio->io_lblkno = bufs[count].b_lblkno;
1384 				hsio->nblocks = howmany(hsio->bp->b_bcount,
1385 				    DEV_BSIZE);
1386 
1387 				/* used for deadline */
1388 				hsio->io_timestamp =
1389 				    drv_hztousec(ddi_get_lbolt());
1390 
1391 				/* for I/O coalescing */
1392 				hsio->contig_chain = NULL;
1393 				hsched_enqueue_io(fsp, hsio, 0);
1394 			}
1395 
1396 			lwp_stat_update(LWP_STAT_INBLK, 1);
1397 			lastp = searchp;
1398 			if ((remainder - bufs[count].b_bcount) < 1) {
1399 				searchp = searchp->p_next;
1400 			}
1401 		}
1402 
1403 		bufsused = count;
1404 		/* Now wait for everything to come in */
1405 		if (fsp->hqueue == NULL) {
1406 			for (count = 0; count < bufsused; count++) {
1407 				if (err == 0) {
1408 					err = biowait(&bufs[count]);
1409 				} else
1410 					(void) biowait(&bufs[count]);
1411 			}
1412 		} else {
1413 			for (count = 0; count < bufsused; count++) {
1414 				struct buf *wbuf;
1415 
1416 				/*
1417 				 * Invoke scheduling function till our buf
1418 				 * is processed. In doing this it might
1419 				 * process bufs enqueued by other threads
1420 				 * which is good.
1421 				 */
1422 				wbuf = &bufs[count];
1423 				DTRACE_PROBE1(hsfs_io_wait, struct buf *, wbuf);
1424 				while (sema_tryp(&fio_done[count]) == 0) {
1425 					/*
1426 					 * hsched_invoke_strategy will return 1
1427 					 * if the I/O queue is empty. This means
1428 					 * that there is another thread who has
1429 					 * issued our buf and is waiting. So we
1430 					 * just block instead of spinning.
1431 					 */
1432 					if (hsched_invoke_strategy(fsp)) {
1433 						sema_p(&fio_done[count]);
1434 						break;
1435 					}
1436 				}
1437 				sema_destroy(&fio_done[count]);
1438 				DTRACE_PROBE1(hsfs_io_done, struct buf *, wbuf);
1439 
1440 				if (err == 0) {
1441 					err = geterror(wbuf);
1442 				}
1443 			}
1444 			kmem_free(fio_done, bufcnt * sizeof (ksema_t));
1445 		}
1446 
1447 		/* Don't leak resources */
1448 		for (count = 0; count < bufcnt; count++) {
1449 			biofini(&bufs[count]);
1450 			if (count < bufsused && vas[count] != NULL) {
1451 				ppmapout(vas[count]);
1452 			}
1453 		}
1454 
1455 		kmem_free(vas, bufcnt * sizeof (caddr_t));
1456 		kmem_free(bufs, bufcnt * sizeof (struct buf));
1457 	}
1458 
1459 	if (err) {
1460 		pvn_read_done(pp, B_ERROR);
1461 		return (err);
1462 	}
1463 
1464 	/*
1465 	 * Lock the requested page, and the one after it if possible.
1466 	 * Don't bother if our caller hasn't given us a place to stash
1467 	 * the page pointers, since otherwise we'd lock pages that would
1468 	 * never get unlocked.
1469 	 */
1470 	if (pagefound) {
1471 		int index;
1472 		ulong_t soff;
1473 
1474 		/*
1475 		 * Make sure it's in memory before we say it's here.
1476 		 */
1477 		if ((pp = page_lookup(vp, off, SE_SHARED)) == NULL) {
1478 			hsfs_lostpage++;
1479 			goto reread;
1480 		}
1481 
1482 		pl[0] = pp;
1483 		index = 1;
1484 		atomic_inc_64(&fsp->cache_read_pages);
1485 
1486 		/*
1487 		 * Try to lock the next page, if it exists, without
1488 		 * blocking.
1489 		 */
1490 		plsz -= PAGESIZE;
1491 		/* LINTED (plsz is unsigned) */
1492 		for (soff = off + PAGESIZE; plsz > 0;
1493 		    soff += PAGESIZE, plsz -= PAGESIZE) {
1494 			pp = page_lookup_nowait(vp, (u_offset_t)soff,
1495 			    SE_SHARED);
1496 			if (pp == NULL)
1497 				break;
1498 			pl[index++] = pp;
1499 		}
1500 		pl[index] = NULL;
1501 
1502 		/*
1503 		 * Schedule a semi-asynchronous readahead if we are
1504 		 * accessing the last cached page for the current
1505 		 * file.
1506 		 *
1507 		 * Doing this here means that readaheads will be
1508 		 * issued only if cache-hits occur. This is an advantage
1509 		 * since cache-hits would mean that readahead is giving
1510 		 * the desired benefit. If cache-hits do not occur there
1511 		 * is no point in reading ahead of time - the system
1512 		 * is loaded anyway.
1513 		 */
1514 		if (fsp->hqueue != NULL &&
1515 		    hp->hs_prev_offset - off == PAGESIZE &&
1516 		    hp->hs_prev_offset < filsiz &&
1517 		    hp->hs_ra_bytes > 0 &&
1518 		    !page_exists(vp, hp->hs_prev_offset)) {
1519 			(void) hsfs_getpage_ra(vp, hp->hs_prev_offset, seg,
1520 			    addr + PAGESIZE, hp, fsp, xarsiz, bof,
1521 			    chunk_lbn_count, chunk_data_bytes);
1522 		}
1523 
1524 		return (0);
1525 	}
1526 
1527 	if (pp != NULL) {
1528 		pvn_plist_init(pp, pl, plsz, off, io_len, rw);
1529 	}
1530 
1531 	return (err);
1532 }
1533 
1534 static int
1535 hsfs_getpage(
1536 	struct vnode *vp,
1537 	offset_t off,
1538 	size_t len,
1539 	uint_t *protp,
1540 	struct page *pl[],
1541 	size_t plsz,
1542 	struct seg *seg,
1543 	caddr_t addr,
1544 	enum seg_rw rw,
1545 	struct cred *cred)
1546 {
1547 	int err;
1548 	uint_t filsiz;
1549 	struct hsfs *fsp;
1550 	struct hsnode *hp;
1551 
1552 	fsp = VFS_TO_HSFS(vp->v_vfsp);
1553 	hp = VTOH(vp);
1554 
1555 	/* does not support write */
1556 	if (rw == S_WRITE) {
1557 		panic("write attempt on READ ONLY HSFS");
1558 		/*NOTREACHED*/
1559 	}
1560 
1561 	if (vp->v_flag & VNOMAP) {
1562 		return (ENOSYS);
1563 	}
1564 
1565 	ASSERT(off <= HS_MAXFILEOFF);
1566 
1567 	/*
1568 	 * Determine file data size for EOF check.
1569 	 */
1570 	filsiz = hp->hs_dirent.ext_size;
1571 	if ((off + len) > (offset_t)(filsiz + PAGEOFFSET) && seg != segkmap)
1572 		return (EFAULT);	/* beyond EOF */
1573 
1574 	/*
1575 	 * Async Read-ahead computation.
1576 	 * This attempts to detect sequential access pattern and
1577 	 * enables reading extra pages ahead of time.
1578 	 */
1579 	if (fsp->hqueue != NULL) {
1580 		/*
1581 		 * This check for sequential access also takes into
1582 		 * account segmap weirdness when reading in chunks
1583 		 * less than the segmap size of 8K.
1584 		 */
1585 		if (hp->hs_prev_offset == off || (off <
1586 		    hp->hs_prev_offset && off + MAX(len, PAGESIZE)
1587 		    >= hp->hs_prev_offset)) {
1588 			if (hp->hs_num_contig <
1589 			    (seq_contig_requests - 1)) {
1590 				hp->hs_num_contig++;
1591 
1592 			} else {
1593 				/*
1594 				 * We increase readahead quantum till
1595 				 * a predefined max. max_readahead_bytes
1596 				 * is a multiple of PAGESIZE.
1597 				 */
1598 				if (hp->hs_ra_bytes <
1599 				    fsp->hqueue->max_ra_bytes) {
1600 					hp->hs_ra_bytes += PAGESIZE;
1601 				}
1602 			}
1603 		} else {
1604 			/*
1605 			 * Not contiguous so reduce read ahead counters.
1606 			 */
1607 			if (hp->hs_ra_bytes > 0)
1608 				hp->hs_ra_bytes -= PAGESIZE;
1609 
1610 			if (hp->hs_ra_bytes <= 0) {
1611 				hp->hs_ra_bytes = 0;
1612 				if (hp->hs_num_contig > 0)
1613 					hp->hs_num_contig--;
1614 			}
1615 		}
1616 		/*
1617 		 * Length must be rounded up to page boundary.
1618 		 * since we read in units of pages.
1619 		 */
1620 		hp->hs_prev_offset = off + roundup(len, PAGESIZE);
1621 		DTRACE_PROBE1(hsfs_compute_ra, struct hsnode *, hp);
1622 	}
1623 	if (protp != NULL)
1624 		*protp = PROT_ALL;
1625 
1626 	if (len <= PAGESIZE)
1627 		err = hsfs_getapage(vp, (u_offset_t)off, len, protp, pl, plsz,
1628 		    seg, addr, rw, cred);
1629 	else
1630 		err = pvn_getpages(hsfs_getapage, vp, off, len, protp,
1631 		    pl, plsz, seg, addr, rw, cred);
1632 
1633 	return (err);
1634 }
1635 
1636 
1637 
1638 /*
1639  * This function should never be called. We need to have it to pass
1640  * it as an argument to other functions.
1641  */
1642 /*ARGSUSED*/
1643 int
1644 hsfs_putapage(
1645 	vnode_t		*vp,
1646 	page_t		*pp,
1647 	u_offset_t	*offp,
1648 	size_t		*lenp,
1649 	int		flags,
1650 	cred_t		*cr)
1651 {
1652 	/* should never happen - just destroy it */
1653 	cmn_err(CE_NOTE, "hsfs_putapage: dirty HSFS page");
1654 	pvn_write_done(pp, B_ERROR | B_WRITE | B_INVAL | B_FORCE | flags);
1655 	return (0);
1656 }
1657 
1658 
1659 /*
1660  * The only flags we support are B_INVAL, B_FREE and B_DONTNEED.
1661  * B_INVAL is set by:
1662  *
1663  *	1) the MC_SYNC command of memcntl(2) to support the MS_INVALIDATE flag.
1664  *	2) the MC_ADVISE command of memcntl(2) with the MADV_DONTNEED advice
1665  *	   which translates to an MC_SYNC with the MS_INVALIDATE flag.
1666  *
1667  * The B_FREE (as well as the B_DONTNEED) flag is set when the
1668  * MADV_SEQUENTIAL advice has been used. VOP_PUTPAGE is invoked
1669  * from SEGVN to release pages behind a pagefault.
1670  */
1671 /*ARGSUSED*/
1672 static int
1673 hsfs_putpage(
1674 	struct vnode	*vp,
1675 	offset_t	off,
1676 	size_t		len,
1677 	int		flags,
1678 	struct cred	*cr)
1679 {
1680 	int error = 0;
1681 
1682 	if (vp->v_count == 0) {
1683 		panic("hsfs_putpage: bad v_count");
1684 		/*NOTREACHED*/
1685 	}
1686 
1687 	if (vp->v_flag & VNOMAP)
1688 		return (ENOSYS);
1689 
1690 	ASSERT(off <= HS_MAXFILEOFF);
1691 
1692 	if (!vn_has_cached_data(vp))	/* no pages mapped */
1693 		return (0);
1694 
1695 	if (len == 0) {		/* from 'off' to EOF */
1696 		error = pvn_vplist_dirty(vp, off, hsfs_putapage, flags, cr);
1697 	} else {
1698 		offset_t end_off = off + len;
1699 		offset_t file_size = VTOH(vp)->hs_dirent.ext_size;
1700 		offset_t io_off;
1701 
1702 		file_size = (file_size + PAGESIZE - 1) & PAGEMASK;
1703 		if (end_off > file_size)
1704 			end_off = file_size;
1705 
1706 		for (io_off = off; io_off < end_off; io_off += PAGESIZE) {
1707 			page_t *pp;
1708 
1709 			/*
1710 			 * We insist on getting the page only if we are
1711 			 * about to invalidate, free or write it and
1712 			 * the B_ASYNC flag is not set.
1713 			 */
1714 			if ((flags & B_INVAL) || ((flags & B_ASYNC) == 0)) {
1715 				pp = page_lookup(vp, io_off,
1716 				    (flags & (B_INVAL | B_FREE)) ?
1717 				    SE_EXCL : SE_SHARED);
1718 			} else {
1719 				pp = page_lookup_nowait(vp, io_off,
1720 				    (flags & B_FREE) ? SE_EXCL : SE_SHARED);
1721 			}
1722 
1723 			if (pp == NULL)
1724 				continue;
1725 
1726 			/*
1727 			 * Normally pvn_getdirty() should return 0, which
1728 			 * impies that it has done the job for us.
1729 			 * The shouldn't-happen scenario is when it returns 1.
1730 			 * This means that the page has been modified and
1731 			 * needs to be put back.
1732 			 * Since we can't write on a CD, we fake a failed
1733 			 * I/O and force pvn_write_done() to destroy the page.
1734 			 */
1735 			if (pvn_getdirty(pp, flags) == 1) {
1736 				cmn_err(CE_NOTE,
1737 				    "hsfs_putpage: dirty HSFS page");
1738 				pvn_write_done(pp, flags |
1739 				    B_ERROR | B_WRITE | B_INVAL | B_FORCE);
1740 			}
1741 		}
1742 	}
1743 	return (error);
1744 }
1745 
1746 
1747 /*ARGSUSED*/
1748 static int
1749 hsfs_map(
1750 	struct vnode *vp,
1751 	offset_t off,
1752 	struct as *as,
1753 	caddr_t *addrp,
1754 	size_t len,
1755 	uchar_t prot,
1756 	uchar_t maxprot,
1757 	uint_t flags,
1758 	struct cred *cred)
1759 {
1760 	struct segvn_crargs vn_a;
1761 	int error;
1762 
1763 	/* VFS_RECORD(vp->v_vfsp, VS_MAP, VS_CALL); */
1764 
1765 	if (vp->v_flag & VNOMAP)
1766 		return (ENOSYS);
1767 
1768 	if (off > HS_MAXFILEOFF || off < 0 ||
1769 	    (off + len) < 0 || (off + len) > HS_MAXFILEOFF)
1770 		return (ENXIO);
1771 
1772 	if (vp->v_type != VREG) {
1773 		return (ENODEV);
1774 	}
1775 
1776 	/*
1777 	 * If file is being locked, disallow mapping.
1778 	 */
1779 	if (vn_has_mandatory_locks(vp, VTOH(vp)->hs_dirent.mode))
1780 		return (EAGAIN);
1781 
1782 	as_rangelock(as);
1783 
1784 	if ((flags & MAP_FIXED) == 0) {
1785 		map_addr(addrp, len, off, 1, flags);
1786 		if (*addrp == NULL) {
1787 			as_rangeunlock(as);
1788 			return (ENOMEM);
1789 		}
1790 	} else {
1791 		/*
1792 		 * User specified address - blow away any previous mappings
1793 		 */
1794 		(void) as_unmap(as, *addrp, len);
1795 	}
1796 
1797 	vn_a.vp = vp;
1798 	vn_a.offset = off;
1799 	vn_a.type = flags & MAP_TYPE;
1800 	vn_a.prot = prot;
1801 	vn_a.maxprot = maxprot;
1802 	vn_a.flags = flags & ~MAP_TYPE;
1803 	vn_a.cred = cred;
1804 	vn_a.amp = NULL;
1805 	vn_a.szc = 0;
1806 	vn_a.lgrp_mem_policy_flags = 0;
1807 
1808 	error = as_map(as, *addrp, len, segvn_create, &vn_a);
1809 	as_rangeunlock(as);
1810 	return (error);
1811 }
1812 
1813 /* ARGSUSED */
1814 static int
1815 hsfs_addmap(
1816 	struct vnode *vp,
1817 	offset_t off,
1818 	struct as *as,
1819 	caddr_t addr,
1820 	size_t len,
1821 	uchar_t prot,
1822 	uchar_t maxprot,
1823 	uint_t flags,
1824 	struct cred *cr)
1825 {
1826 	struct hsnode *hp;
1827 
1828 	if (vp->v_flag & VNOMAP)
1829 		return (ENOSYS);
1830 
1831 	hp = VTOH(vp);
1832 	mutex_enter(&hp->hs_contents_lock);
1833 	hp->hs_mapcnt += btopr(len);
1834 	mutex_exit(&hp->hs_contents_lock);
1835 	return (0);
1836 }
1837 
1838 /*ARGSUSED*/
1839 static int
1840 hsfs_delmap(
1841 	struct vnode *vp,
1842 	offset_t off,
1843 	struct as *as,
1844 	caddr_t addr,
1845 	size_t len,
1846 	uint_t prot,
1847 	uint_t maxprot,
1848 	uint_t flags,
1849 	struct cred *cr)
1850 {
1851 	struct hsnode *hp;
1852 
1853 	if (vp->v_flag & VNOMAP)
1854 		return (ENOSYS);
1855 
1856 	hp = VTOH(vp);
1857 	mutex_enter(&hp->hs_contents_lock);
1858 	hp->hs_mapcnt -= btopr(len);	/* Count released mappings */
1859 	ASSERT(hp->hs_mapcnt >= 0);
1860 	mutex_exit(&hp->hs_contents_lock);
1861 	return (0);
1862 }
1863 
1864 /* ARGSUSED */
1865 static int
1866 hsfs_seek(struct vnode *vp, offset_t ooff, offset_t *noffp)
1867 {
1868 	return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0);
1869 }
1870 
1871 /* ARGSUSED */
1872 static int
1873 hsfs_frlock(
1874 	struct vnode *vp,
1875 	int cmd,
1876 	struct flock64 *bfp,
1877 	int flag,
1878 	offset_t offset,
1879 	struct flk_callback *flk_cbp,
1880 	cred_t *cr)
1881 {
1882 	struct hsnode *hp = VTOH(vp);
1883 
1884 	/*
1885 	 * If the file is being mapped, disallow fs_frlock.
1886 	 * We are not holding the hs_contents_lock while checking
1887 	 * hs_mapcnt because the current locking strategy drops all
1888 	 * locks before calling fs_frlock.
1889 	 * So, hs_mapcnt could change before we enter fs_frlock making
1890 	 * it meaningless to have held hs_contents_lock in the first place.
1891 	 */
1892 	if (hp->hs_mapcnt > 0 && MANDLOCK(vp, hp->hs_dirent.mode))
1893 		return (EAGAIN);
1894 
1895 	return (fs_frlock(vp, cmd, bfp, flag, offset, flk_cbp, cr));
1896 }
1897 
1898 static int
1899 hsched_deadline_compare(const void *x1, const void *x2)
1900 {
1901 	const struct hio *h1 = x1;
1902 	const struct hio *h2 = x2;
1903 
1904 	if (h1->io_timestamp < h2->io_timestamp)
1905 		return (-1);
1906 	if (h1->io_timestamp > h2->io_timestamp)
1907 		return (1);
1908 
1909 	if (h1->io_lblkno < h2->io_lblkno)
1910 		return (-1);
1911 	if (h1->io_lblkno > h2->io_lblkno)
1912 		return (1);
1913 
1914 	if (h1 < h2)
1915 		return (-1);
1916 	if (h1 > h2)
1917 		return (1);
1918 
1919 	return (0);
1920 }
1921 
1922 static int
1923 hsched_offset_compare(const void *x1, const void *x2)
1924 {
1925 	const struct hio *h1 = x1;
1926 	const struct hio *h2 = x2;
1927 
1928 	if (h1->io_lblkno < h2->io_lblkno)
1929 		return (-1);
1930 	if (h1->io_lblkno > h2->io_lblkno)
1931 		return (1);
1932 
1933 	if (h1 < h2)
1934 		return (-1);
1935 	if (h1 > h2)
1936 		return (1);
1937 
1938 	return (0);
1939 }
1940 
1941 void
1942 hsched_init_caches(void)
1943 {
1944 	hio_cache = kmem_cache_create("hsfs_hio_cache",
1945 	    sizeof (struct hio), 0, NULL,
1946 	    NULL, NULL, NULL, NULL, 0);
1947 
1948 	hio_info_cache = kmem_cache_create("hsfs_hio_info_cache",
1949 	    sizeof (struct hio_info), 0, NULL,
1950 	    NULL, NULL, NULL, NULL, 0);
1951 }
1952 
1953 void
1954 hsched_fini_caches(void)
1955 {
1956 	kmem_cache_destroy(hio_cache);
1957 	kmem_cache_destroy(hio_info_cache);
1958 }
1959 
1960 /*
1961  * Initialize I/O scheduling structures. This is called via hsfs_mount
1962  */
1963 void
1964 hsched_init(struct hsfs *fsp, int fsid, struct modlinkage *modlinkage)
1965 {
1966 	struct hsfs_queue *hqueue = fsp->hqueue;
1967 	struct vnode *vp = fsp->hsfs_devvp;
1968 
1969 	/* TaskQ name of the form: hsched_task_ + stringof(int) */
1970 	char namebuf[23];
1971 	int error, err;
1972 	struct dk_cinfo info;
1973 	ldi_handle_t lh;
1974 	ldi_ident_t li;
1975 
1976 	/*
1977 	 * Default maxtransfer = 16k chunk
1978 	 */
1979 	hqueue->dev_maxtransfer = 16384;
1980 
1981 	/*
1982 	 * Try to fetch the maximum device transfer size. This is used to
1983 	 * ensure that a coalesced block does not exceed the maxtransfer.
1984 	 */
1985 	err  = ldi_ident_from_mod(modlinkage, &li);
1986 	if (err) {
1987 		cmn_err(CE_NOTE, "hsched_init: Querying device failed");
1988 		cmn_err(CE_NOTE, "hsched_init: ldi_ident_from_mod err=%d\n",
1989 		    err);
1990 		goto set_ra;
1991 	}
1992 
1993 	err = ldi_open_by_dev(&(vp->v_rdev), OTYP_CHR, FREAD, CRED(), &lh, li);
1994 	ldi_ident_release(li);
1995 	if (err) {
1996 		cmn_err(CE_NOTE, "hsched_init: Querying device failed");
1997 		cmn_err(CE_NOTE, "hsched_init: ldi_open err=%d\n", err);
1998 		goto set_ra;
1999 	}
2000 
2001 	error = ldi_ioctl(lh, DKIOCINFO, (intptr_t)&info, FKIOCTL,
2002 	    CRED(), &err);
2003 	err = ldi_close(lh, FREAD, CRED());
2004 	if (err) {
2005 		cmn_err(CE_NOTE, "hsched_init: Querying device failed");
2006 		cmn_err(CE_NOTE, "hsched_init: ldi_close err=%d\n", err);
2007 	}
2008 
2009 	if (error == 0) {
2010 		hqueue->dev_maxtransfer = ldbtob(info.dki_maxtransfer);
2011 	}
2012 
2013 set_ra:
2014 	/*
2015 	 * Max size of data to read ahead for sequential access pattern.
2016 	 * Conservative to avoid letting the underlying CD drive to spin
2017 	 * down, in case the application is reading slowly.
2018 	 * We read ahead upto a max of 4 pages.
2019 	 */
2020 	hqueue->max_ra_bytes = PAGESIZE * 8;
2021 
2022 	mutex_init(&(hqueue->hsfs_queue_lock), NULL, MUTEX_DEFAULT, NULL);
2023 	mutex_init(&(hqueue->strategy_lock), NULL, MUTEX_DEFAULT, NULL);
2024 	avl_create(&(hqueue->read_tree), hsched_offset_compare,
2025 	    sizeof (struct hio), offsetof(struct hio, io_offset_node));
2026 	avl_create(&(hqueue->deadline_tree), hsched_deadline_compare,
2027 	    sizeof (struct hio), offsetof(struct hio, io_deadline_node));
2028 
2029 	(void) snprintf(namebuf, sizeof (namebuf), "hsched_task_%d", fsid);
2030 	hqueue->ra_task = taskq_create(namebuf, hsfs_taskq_nthreads,
2031 	    minclsyspri + 2, 1, 104857600 / PAGESIZE, TASKQ_DYNAMIC);
2032 
2033 	hqueue->next = NULL;
2034 	hqueue->nbuf = kmem_zalloc(sizeof (struct buf), KM_SLEEP);
2035 }
2036 
2037 void
2038 hsched_fini(struct hsfs_queue *hqueue)
2039 {
2040 	if (hqueue != NULL) {
2041 		avl_destroy(&(hqueue->read_tree));
2042 		avl_destroy(&(hqueue->deadline_tree));
2043 		mutex_destroy(&(hqueue->hsfs_queue_lock));
2044 		mutex_destroy(&(hqueue->strategy_lock));
2045 
2046 		/*
2047 		 * If there are any existing readahead threads running
2048 		 * taskq_destroy will wait for them to finish.
2049 		 */
2050 		taskq_destroy(hqueue->ra_task);
2051 		if (hqueue->next != NULL) {
2052 			kmem_cache_free(hio_cache, hqueue->next);
2053 		}
2054 		kmem_free(hqueue->nbuf, sizeof (struct buf));
2055 	}
2056 }
2057 
2058 /*
2059  * Determine if two I/O requests are adjacent to each other so
2060  * that they can coalesced.
2061  */
2062 #define	IS_ADJACENT(io, nio) \
2063 	(((io)->io_lblkno + (io)->nblocks == (nio)->io_lblkno) && \
2064 	(io)->bp->b_edev == (nio)->bp->b_edev)
2065 
2066 /*
2067  * This performs the actual I/O scheduling logic. We use the Circular
2068  * Look algorithm here. Sort the I/O requests in ascending order of
2069  * logical block number and process them starting with the lowest
2070  * numbered block and progressing towards higher block numbers in the
2071  * queue. Once there are no more higher numbered blocks, start again
2072  * with the lowest one. This is good for CD/DVD as you keep moving
2073  * the head in one direction along the outward spiral track and avoid
2074  * too many seeks as much as possible. The re-ordering also allows
2075  * us to coalesce adjacent requests into one larger request.
2076  * This is thus essentially a 1-way Elevator with front merging.
2077  *
2078  * In addition each read request here has a deadline and will be
2079  * processed out of turn if the deadline (500ms) expires.
2080  *
2081  * This function is necessarily serialized via hqueue->strategy_lock.
2082  * This function sits just below hsfs_getapage and processes all read
2083  * requests orginating from that function.
2084  */
2085 int
2086 hsched_invoke_strategy(struct hsfs *fsp)
2087 {
2088 	struct hsfs_queue *hqueue;
2089 	struct buf *nbuf;
2090 	struct hio *fio, *nio, *tio, *prev, *last;
2091 	size_t bsize, soffset, offset, data;
2092 	int bioret, bufcount;
2093 	struct vnode *fvp;
2094 	ksema_t *io_done;
2095 	caddr_t iodata;
2096 
2097 	hqueue = fsp->hqueue;
2098 	mutex_enter(&hqueue->strategy_lock);
2099 	mutex_enter(&hqueue->hsfs_queue_lock);
2100 
2101 	/*
2102 	 * Check for Deadline expiration first
2103 	 */
2104 	fio = avl_first(&hqueue->deadline_tree);
2105 
2106 	/*
2107 	 * Paranoid check for empty I/O queue. Both deadline
2108 	 * and read trees contain same data sorted in different
2109 	 * ways. So empty deadline tree = empty read tree.
2110 	 */
2111 	if (fio == NULL) {
2112 		/*
2113 		 * Remove the sentinel if there was one.
2114 		 */
2115 		if (hqueue->next != NULL) {
2116 			avl_remove(&hqueue->read_tree, hqueue->next);
2117 			kmem_cache_free(hio_cache, hqueue->next);
2118 			hqueue->next = NULL;
2119 		}
2120 		mutex_exit(&hqueue->hsfs_queue_lock);
2121 		mutex_exit(&hqueue->strategy_lock);
2122 		return (1);
2123 	}
2124 
2125 	if (drv_hztousec(ddi_get_lbolt()) - fio->io_timestamp
2126 	    < HSFS_READ_DEADLINE) {
2127 		/*
2128 		 * Apply standard scheduling logic. This uses the
2129 		 * C-LOOK approach. Process I/O requests in ascending
2130 		 * order of logical block address till no subsequent
2131 		 * higher numbered block request remains. Then start
2132 		 * again from the lowest numbered block in the queue.
2133 		 *
2134 		 * We do this cheaply here by means of a sentinel.
2135 		 * The last processed I/O structure from the previous
2136 		 * invocation of this func, is left dangling in the
2137 		 * read_tree so that we can easily scan to the next
2138 		 * higher numbered request and remove the sentinel.
2139 		 */
2140 		fio = NULL;
2141 		if (hqueue->next != NULL) {
2142 			fio = AVL_NEXT(&hqueue->read_tree, hqueue->next);
2143 			avl_remove(&hqueue->read_tree, hqueue->next);
2144 			kmem_cache_free(hio_cache, hqueue->next);
2145 			hqueue->next = NULL;
2146 		}
2147 		if (fio == NULL) {
2148 			fio = avl_first(&hqueue->read_tree);
2149 		}
2150 	} else if (hqueue->next != NULL) {
2151 		DTRACE_PROBE1(hsfs_deadline_expiry, struct hio *, fio);
2152 
2153 		avl_remove(&hqueue->read_tree, hqueue->next);
2154 		kmem_cache_free(hio_cache, hqueue->next);
2155 		hqueue->next = NULL;
2156 	}
2157 
2158 	/*
2159 	 * In addition we try to coalesce contiguous
2160 	 * requests into one bigger request.
2161 	 */
2162 	bufcount = 1;
2163 	bsize = ldbtob(fio->nblocks);
2164 	fvp = fio->bp->b_file;
2165 	nio = AVL_NEXT(&hqueue->read_tree, fio);
2166 	tio = fio;
2167 	while (nio != NULL && IS_ADJACENT(tio, nio) &&
2168 	    bsize < hqueue->dev_maxtransfer) {
2169 		avl_remove(&hqueue->deadline_tree, tio);
2170 		avl_remove(&hqueue->read_tree, tio);
2171 		tio->contig_chain = nio;
2172 		bsize += ldbtob(nio->nblocks);
2173 		prev = tio;
2174 		tio = nio;
2175 
2176 		/*
2177 		 * This check is required to detect the case where
2178 		 * we are merging adjacent buffers belonging to
2179 		 * different files. fvp is used to set the b_file
2180 		 * parameter in the coalesced buf. b_file is used
2181 		 * by DTrace so we do not want DTrace to accrue
2182 		 * requests to two different files to any one file.
2183 		 */
2184 		if (fvp && tio->bp->b_file != fvp) {
2185 			fvp = NULL;
2186 		}
2187 
2188 		nio = AVL_NEXT(&hqueue->read_tree, nio);
2189 		bufcount++;
2190 	}
2191 
2192 	/*
2193 	 * tio is not removed from the read_tree as it serves as a sentinel
2194 	 * to cheaply allow us to scan to the next higher numbered I/O
2195 	 * request.
2196 	 */
2197 	hqueue->next = tio;
2198 	avl_remove(&hqueue->deadline_tree, tio);
2199 	mutex_exit(&hqueue->hsfs_queue_lock);
2200 	DTRACE_PROBE3(hsfs_io_dequeued, struct hio *, fio, int, bufcount,
2201 	    size_t, bsize);
2202 
2203 	/*
2204 	 * The benefit of coalescing occurs if the the savings in I/O outweighs
2205 	 * the cost of doing the additional work below.
2206 	 * It was observed that coalescing 2 buffers results in diminishing
2207 	 * returns, so we do coalescing if we have >2 adjacent bufs.
2208 	 */
2209 	if (bufcount > hsched_coalesce_min) {
2210 		/*
2211 		 * We have coalesced blocks. First allocate mem and buf for
2212 		 * the entire coalesced chunk.
2213 		 * Since we are guaranteed single-threaded here we pre-allocate
2214 		 * one buf at mount time and that is re-used every time. This
2215 		 * is a synthesized buf structure that uses kmem_alloced chunk.
2216 		 * Not quite a normal buf attached to pages.
2217 		 */
2218 		fsp->coalesced_bytes += bsize;
2219 		nbuf = hqueue->nbuf;
2220 		bioinit(nbuf);
2221 		nbuf->b_edev = fio->bp->b_edev;
2222 		nbuf->b_dev = fio->bp->b_dev;
2223 		nbuf->b_flags = fio->bp->b_flags;
2224 		nbuf->b_iodone = fio->bp->b_iodone;
2225 		iodata = kmem_alloc(bsize, KM_SLEEP);
2226 		nbuf->b_un.b_addr = iodata;
2227 		nbuf->b_lblkno = fio->bp->b_lblkno;
2228 		nbuf->b_vp = fvp;
2229 		nbuf->b_file = fvp;
2230 		nbuf->b_bcount = bsize;
2231 		nbuf->b_bufsize = bsize;
2232 		nbuf->b_resid = bsize;
2233 
2234 		DTRACE_PROBE3(hsfs_coalesced_io_start, struct hio *, fio, int,
2235 		    bufcount, size_t, bsize);
2236 
2237 		/*
2238 		 * Perform I/O for the coalesced block.
2239 		 */
2240 		(void) bdev_strategy(nbuf);
2241 
2242 		/*
2243 		 * Duplicate the last IO node to leave the sentinel alone.
2244 		 * The sentinel is freed in the next invocation of this
2245 		 * function.
2246 		 */
2247 		prev->contig_chain = kmem_cache_alloc(hio_cache, KM_SLEEP);
2248 		prev->contig_chain->bp = tio->bp;
2249 		prev->contig_chain->sema = tio->sema;
2250 		tio = prev->contig_chain;
2251 		tio->contig_chain = NULL;
2252 		soffset = ldbtob(fio->bp->b_lblkno);
2253 		nio = fio;
2254 
2255 		bioret = biowait(nbuf);
2256 		data = bsize - nbuf->b_resid;
2257 		biofini(nbuf);
2258 		mutex_exit(&hqueue->strategy_lock);
2259 
2260 		/*
2261 		 * We use the b_resid parameter to detect how much
2262 		 * data was succesfully transferred. We will signal
2263 		 * a success to all the fully retrieved actual bufs
2264 		 * before coalescing, rest is signaled as error,
2265 		 * if any.
2266 		 */
2267 		tio = nio;
2268 		DTRACE_PROBE3(hsfs_coalesced_io_done, struct hio *, nio,
2269 		    int, bioret, size_t, data);
2270 
2271 		/*
2272 		 * Copy data and signal success to all the bufs
2273 		 * which can be fully satisfied from b_resid.
2274 		 */
2275 		while (nio != NULL && data >= nio->bp->b_bcount) {
2276 			offset = ldbtob(nio->bp->b_lblkno) - soffset;
2277 			bcopy(iodata + offset, nio->bp->b_un.b_addr,
2278 			    nio->bp->b_bcount);
2279 			data -= nio->bp->b_bcount;
2280 			bioerror(nio->bp, 0);
2281 			biodone(nio->bp);
2282 			sema_v(nio->sema);
2283 			tio = nio;
2284 			nio = nio->contig_chain;
2285 			kmem_cache_free(hio_cache, tio);
2286 		}
2287 
2288 		/*
2289 		 * Signal error to all the leftover bufs (if any)
2290 		 * after b_resid data is exhausted.
2291 		 */
2292 		while (nio != NULL) {
2293 			nio->bp->b_resid = nio->bp->b_bcount - data;
2294 			bzero(nio->bp->b_un.b_addr + data, nio->bp->b_resid);
2295 			bioerror(nio->bp, bioret);
2296 			biodone(nio->bp);
2297 			sema_v(nio->sema);
2298 			tio = nio;
2299 			nio = nio->contig_chain;
2300 			kmem_cache_free(hio_cache, tio);
2301 			data = 0;
2302 		}
2303 		kmem_free(iodata, bsize);
2304 	} else {
2305 
2306 		nbuf = tio->bp;
2307 		io_done = tio->sema;
2308 		nio = fio;
2309 		last = tio;
2310 
2311 		while (nio != NULL) {
2312 			(void) bdev_strategy(nio->bp);
2313 			nio = nio->contig_chain;
2314 		}
2315 		nio = fio;
2316 		mutex_exit(&hqueue->strategy_lock);
2317 
2318 		while (nio != NULL) {
2319 			if (nio == last) {
2320 				(void) biowait(nbuf);
2321 				sema_v(io_done);
2322 				break;
2323 				/* sentinel last not freed. See above. */
2324 			} else {
2325 				(void) biowait(nio->bp);
2326 				sema_v(nio->sema);
2327 			}
2328 			tio = nio;
2329 			nio = nio->contig_chain;
2330 			kmem_cache_free(hio_cache, tio);
2331 		}
2332 	}
2333 	return (0);
2334 }
2335 
2336 /*
2337  * Insert an I/O request in the I/O scheduler's pipeline
2338  * Using AVL tree makes it easy to reorder the I/O request
2339  * based on logical block number.
2340  */
2341 static void
2342 hsched_enqueue_io(struct hsfs *fsp, struct hio *hsio, int ra)
2343 {
2344 	struct hsfs_queue *hqueue = fsp->hqueue;
2345 
2346 	mutex_enter(&hqueue->hsfs_queue_lock);
2347 
2348 	fsp->physical_read_bytes += hsio->bp->b_bcount;
2349 	if (ra)
2350 		fsp->readahead_bytes += hsio->bp->b_bcount;
2351 
2352 	avl_add(&hqueue->deadline_tree, hsio);
2353 	avl_add(&hqueue->read_tree, hsio);
2354 
2355 	DTRACE_PROBE3(hsfs_io_enqueued, struct hio *, hsio,
2356 	    struct hsfs_queue *, hqueue, int, ra);
2357 
2358 	mutex_exit(&hqueue->hsfs_queue_lock);
2359 }
2360 
2361 /* ARGSUSED */
2362 static int
2363 hsfs_pathconf(struct vnode *vp, int cmd, ulong_t *valp, struct cred *cr)
2364 {
2365 	struct hsfs	*fsp;
2366 
2367 	int		error = 0;
2368 
2369 	switch (cmd) {
2370 
2371 	case _PC_NAME_MAX:
2372 		fsp = VFS_TO_HSFS(vp->v_vfsp);
2373 		*valp = fsp->hsfs_namemax;
2374 		break;
2375 
2376 	case _PC_FILESIZEBITS:
2377 		*valp = 33;	/* Without multi extent support: 4 GB - 2k */
2378 		break;
2379 
2380 	default:
2381 		error = fs_pathconf(vp, cmd, valp, cr);
2382 	}
2383 
2384 	return (error);
2385 }
2386 
2387 
2388 
2389 const fs_operation_def_t hsfs_vnodeops_template[] = {
2390 	VOPNAME_OPEN,		{ .vop_open = hsfs_open },
2391 	VOPNAME_CLOSE,		{ .vop_close = hsfs_close },
2392 	VOPNAME_READ,		{ .vop_read = hsfs_read },
2393 	VOPNAME_GETATTR,	{ .vop_getattr = hsfs_getattr },
2394 	VOPNAME_ACCESS,		{ .vop_access = hsfs_access },
2395 	VOPNAME_LOOKUP,		{ .vop_lookup = hsfs_lookup },
2396 	VOPNAME_READDIR,	{ .vop_readdir = hsfs_readdir },
2397 	VOPNAME_READLINK,	{ .vop_readlink = hsfs_readlink },
2398 	VOPNAME_FSYNC,		{ .vop_fsync = hsfs_fsync },
2399 	VOPNAME_INACTIVE,	{ .vop_inactive = hsfs_inactive },
2400 	VOPNAME_FID,		{ .vop_fid = hsfs_fid },
2401 	VOPNAME_SEEK,		{ .vop_seek = hsfs_seek },
2402 	VOPNAME_FRLOCK,		{ .vop_frlock = hsfs_frlock },
2403 	VOPNAME_GETPAGE,	{ .vop_getpage = hsfs_getpage },
2404 	VOPNAME_PUTPAGE,	{ .vop_putpage = hsfs_putpage },
2405 	VOPNAME_MAP,		{ .vop_map = hsfs_map },
2406 	VOPNAME_ADDMAP,		{ .vop_addmap = hsfs_addmap },
2407 	VOPNAME_DELMAP,		{ .vop_delmap = hsfs_delmap },
2408 	VOPNAME_PATHCONF,	{ .vop_pathconf = hsfs_pathconf },
2409 	NULL,			NULL
2410 };
2411 
2412 struct vnodeops *hsfs_vnodeops;
2413