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 */
99 static 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 */
115 static int hsfs_taskq_nthreads = 8; /* # of taskq threads per fs */
116
117 /* Min count of adjacent bufs that will avoid buf coalescing */
118 static 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 */
125 struct kmem_cache *hio_cache;
126 struct 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 */
132 extern 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 */
140 static int freebehind = 1;
141 static int smallfile = 0;
142 static int cache_read_ahead = 0;
143 static u_offset_t smallfile64 = 32 * 1024;
144 #define SMALLFILE1_D 1000
145 #define SMALLFILE2_D 10
146 static u_offset_t smallfile1 = 32 * 1024;
147 static u_offset_t smallfile2 = 32 * 1024;
148 static clock_t smallfile_update = 0; /* when to recompute */
149 static uint_t smallfile1_d = SMALLFILE1_D;
150 static uint_t smallfile2_d = SMALLFILE2_D;
151
152 static int hsched_deadline_compare(const void *x1, const void *x2);
153 static int hsched_offset_compare(const void *x1, const void *x2);
154 static void hsched_enqueue_io(struct hsfs *fsp, struct hio *hsio, int ra);
155 int hsched_invoke_strategy(struct hsfs *fsp);
156
157 /* ARGSUSED */
158 static int
hsfs_fsync(vnode_t * cp,int syncflag,cred_t * cred,caller_context_t * ct)159 hsfs_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*/
169 static int
hsfs_read(struct vnode * vp,struct uio * uiop,int ioflag,struct cred * cred,struct caller_context * ct)170 hsfs_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*/
302 static int
hsfs_getattr(struct vnode * vp,struct vattr * vap,int flags,struct cred * cred,caller_context_t * ct)303 hsfs_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*/
350 static int
hsfs_readlink(struct vnode * vp,struct uio * uiop,struct cred * cred,caller_context_t * ct)351 hsfs_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*/
372 static void
hsfs_inactive(struct vnode * vp,struct cred * cred,caller_context_t * ct)373 hsfs_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*/
433 static int
hsfs_lookup(struct vnode * dvp,char * nm,struct vnode ** vpp,struct pathname * pnp,int flags,struct vnode * rdir,struct cred * cred,caller_context_t * ct,int * direntflags,pathname_t * realpnp)434 hsfs_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*/
471 static int
hsfs_readdir(struct vnode * vp,struct uio * uiop,struct cred * cred,int * eofp,caller_context_t * ct,int flags)472 hsfs_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 */
640 done:
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*/
654 static int
hsfs_fid(struct vnode * vp,struct fid * fidp,caller_context_t * ct)655 hsfs_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*/
677 static int
hsfs_open(struct vnode ** vpp,int flag,struct cred * cred,caller_context_t * ct)678 hsfs_open(struct vnode **vpp,
679 int flag,
680 struct cred *cred,
681 caller_context_t *ct)
682 {
683 return (0);
684 }
685
686 /*ARGSUSED*/
687 static int
hsfs_close(struct vnode * vp,int flag,int count,offset_t offset,struct cred * cred,caller_context_t * ct)688 hsfs_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*/
702 static int
hsfs_access(struct vnode * vp,int mode,int flags,cred_t * cred,caller_context_t * ct)703 hsfs_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 */
726 int 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*/
733 int
hsfs_iodone(struct buf * bp)734 hsfs_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 */
745 void
hsfs_ra_task(void * arg)746 hsfs_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*/
795 static int
hsfs_getpage_ra(struct vnode * vp,u_offset_t off,struct seg * seg,caddr_t addr,struct hsnode * hp,struct hsfs * fsp,int xarsiz,offset_t bof,int chunk_lbn_count,int chunk_data_bytes)796 hsfs_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*/
1083 static int
hsfs_getapage(struct vnode * vp,u_offset_t off,size_t len,uint_t * protp,struct page * pl[],size_t plsz,struct seg * seg,caddr_t addr,enum seg_rw rw,struct cred * cred)1084 hsfs_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
1181 reread:
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;
1208 again:
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*/
1564 static int
hsfs_getpage(struct vnode * vp,offset_t off,size_t len,uint_t * protp,struct page * pl[],size_t plsz,struct seg * seg,caddr_t addr,enum seg_rw rw,struct cred * cred,caller_context_t * ct)1565 hsfs_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*/
1674 int
hsfs_putapage(vnode_t * vp,page_t * pp,u_offset_t * offp,size_t * lenp,int flags,cred_t * cr)1675 hsfs_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*/
1703 static int
hsfs_putpage(struct vnode * vp,offset_t off,size_t len,int flags,struct cred * cr,caller_context_t * ct)1704 hsfs_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*/
1780 static int
hsfs_map(struct vnode * vp,offset_t off,struct as * as,caddr_t * addrp,size_t len,uchar_t prot,uchar_t maxprot,uint_t flags,struct cred * cred,caller_context_t * ct)1781 hsfs_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 */
1839 static int
hsfs_addmap(struct vnode * vp,offset_t off,struct as * as,caddr_t addr,size_t len,uchar_t prot,uchar_t maxprot,uint_t flags,struct cred * cr,caller_context_t * ct)1840 hsfs_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*/
1865 static int
hsfs_delmap(struct vnode * vp,offset_t off,struct as * as,caddr_t addr,size_t len,uint_t prot,uint_t maxprot,uint_t flags,struct cred * cr,caller_context_t * ct)1866 hsfs_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 */
1892 static int
hsfs_seek(struct vnode * vp,offset_t ooff,offset_t * noffp,caller_context_t * ct)1893 hsfs_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 */
1903 static int
hsfs_frlock(struct vnode * vp,int cmd,struct flock64 * bfp,int flag,offset_t offset,struct flk_callback * flk_cbp,cred_t * cr,caller_context_t * ct)1904 hsfs_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
1930 static int
hsched_deadline_compare(const void * x1,const void * x2)1931 hsched_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
1954 static int
hsched_offset_compare(const void * x1,const void * x2)1955 hsched_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
1973 void
hsched_init_caches(void)1974 hsched_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
1985 void
hsched_fini_caches(void)1986 hsched_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 */
1995 void
hsched_init(struct hsfs * fsp,int fsid,struct modlinkage * modlinkage)1996 hsched_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
2045 set_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
2069 void
hsched_fini(struct hsfs_queue * hqueue)2070 hsched_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 */
2121 int
hsched_invoke_strategy(struct hsfs * fsp)2122 hsched_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 */
2376 static void
hsched_enqueue_io(struct hsfs * fsp,struct hio * hsio,int ra)2377 hsched_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 */
2397 static int
hsfs_pathconf(struct vnode * vp,int cmd,ulong_t * valp,struct cred * cr,caller_context_t * ct)2398 hsfs_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
2436 const 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
2459 struct vnodeops *hsfs_vnodeops;
2460