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