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