ffs_rawread.c revision 136966
162143Sarchie/*- 262143Sarchie * Copyright (c) 2000-2003 Tor Egge 362143Sarchie * All rights reserved. 4139823Simp * 5139823Simp * Redistribution and use in source and binary forms, with or without 6139823Simp * modification, are permitted provided that the following conditions 762143Sarchie * are met: 862143Sarchie * 1. Redistributions of source code must retain the above copyright 962143Sarchie * notice, this list of conditions and the following disclaimer. 1062143Sarchie * 2. Redistributions in binary form must reproduce the above copyright 1162143Sarchie * notice, this list of conditions and the following disclaimer in the 1262143Sarchie * documentation and/or other materials provided with the distribution. 1362143Sarchie * 1462143Sarchie * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1562143Sarchie * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1662143Sarchie * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1762143Sarchie * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1862143Sarchie * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1962143Sarchie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2062143Sarchie * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2162143Sarchie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2262143Sarchie * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2362143Sarchie * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2462143Sarchie * SUCH DAMAGE. 2562143Sarchie */ 2662143Sarchie 2762143Sarchie#include <sys/cdefs.h> 2862143Sarchie__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_rawread.c 136966 2004-10-26 07:39:12Z phk $"); 2962143Sarchie 3062143Sarchie#include <sys/param.h> 3162143Sarchie#include <sys/systm.h> 3262143Sarchie#include <sys/fcntl.h> 3362143Sarchie#include <sys/file.h> 3462143Sarchie#include <sys/stat.h> 3562143Sarchie#include <sys/proc.h> 3662143Sarchie#include <sys/limits.h> 3762143Sarchie#include <sys/mount.h> 3862143Sarchie#include <sys/namei.h> 3962143Sarchie#include <sys/vnode.h> 4062143Sarchie#include <sys/conf.h> 4162143Sarchie#include <sys/filio.h> 4262143Sarchie#include <sys/ttycom.h> 4362143Sarchie#include <sys/bio.h> 4462143Sarchie#include <sys/buf.h> 4562143Sarchie#include <ufs/ufs/extattr.h> 4662143Sarchie#include <ufs/ufs/quota.h> 4762143Sarchie#include <ufs/ufs/inode.h> 4862143Sarchie#include <ufs/ufs/ufsmount.h> 4962143Sarchie#include <ufs/ufs/ufs_extern.h> 5062143Sarchie#include <ufs/ffs/fs.h> 5162143Sarchie 5262143Sarchie#include <vm/vm.h> 5362143Sarchie#include <vm/vm_extern.h> 5462143Sarchie#include <vm/vm_object.h> 5562143Sarchie#include <sys/kernel.h> 5662143Sarchie#include <sys/sysctl.h> 5762143Sarchie 58136428Sglebiusstatic int ffs_rawread_readahead(struct vnode *vp, 5962143Sarchie caddr_t udata, 60141721Sglebius off_t offset, 6162143Sarchie size_t len, 6262143Sarchie struct thread *td, 6362143Sarchie struct buf *bp, 6462143Sarchie caddr_t sa); 6562143Sarchiestatic int ffs_rawread_main(struct vnode *vp, 6662143Sarchie struct uio *uio); 6762143Sarchie 6862143Sarchiestatic int ffs_rawread_sync(struct vnode *vp, struct thread *td); 6962143Sarchie 7062143Sarchieint ffs_rawread(struct vnode *vp, struct uio *uio, int *workdone); 71147256Sbrooks 72147256Sbrooksvoid ffs_rawread_setup(void); 7362143Sarchie 74126035Spjdstatic void ffs_rawreadwakeup(struct buf *bp); 75126035Spjd 76126035Spjd 77126035SpjdSYSCTL_DECL(_vfs_ffs); 78129281Sarchie 79129281Sarchiestatic int ffsrawbufcnt = 4; 80126035SpjdSYSCTL_INT(_vfs_ffs, OID_AUTO, ffsrawbufcnt, CTLFLAG_RD, &ffsrawbufcnt, 0, 81126035Spjd "Buffers available for raw reads"); 82126035Spjd 83126035Spjdstatic int allowrawread = 1; 84126035SpjdSYSCTL_INT(_vfs_ffs, OID_AUTO, allowrawread, CTLFLAG_RW, &allowrawread, 0, 85126035Spjd "Flag to enable raw reads"); 8662143Sarchie 87106933Ssamstatic int rawreadahead = 1; 88106933SsamSYSCTL_INT(_vfs_ffs, OID_AUTO, rawreadahead, CTLFLAG_RW, &rawreadahead, 0, 89106933Ssam "Flag to enable readahead for long raw reads"); 90106933Ssam 91106933Ssam 92106933Ssamvoid 93139903Sglebiusffs_rawread_setup(void) 94106933Ssam{ 9562143Sarchie ffsrawbufcnt = (nswbuf > 100 ) ? (nswbuf - (nswbuf >> 4)) : nswbuf - 8; 96106933Ssam} 97106933Ssam 9862143Sarchie 9962143Sarchiestatic int 10062143Sarchieffs_rawread_sync(struct vnode *vp, struct thread *td) 101139903Sglebius{ 10262143Sarchie int spl; 10362143Sarchie int error; 104131155Sjulian int upgraded; 105131155Sjulian struct bufobj *bo; 10662143Sarchie 10762143Sarchie GIANT_REQUIRED; 10862143Sarchie /* Check for dirty mmap, pending writes and dirty buffers */ 10962143Sarchie spl = splbio(); 11070700Sjulian VI_LOCK(vp); 11162143Sarchie bo = &vp->v_bufobj; 11269922Sjulian if (bo->bo_numoutput > 0 || 11362143Sarchie bo->bo_dirty.bv_cnt > 0) || 11462143Sarchie (vp->v_iflag & VI_OBJDIRTY) != 0) { 11562143Sarchie splx(spl); 11662143Sarchie VI_UNLOCK(vp); 11762143Sarchie 11862143Sarchie if (VOP_ISLOCKED(vp, td) != LK_EXCLUSIVE) { 11962143Sarchie upgraded = 1; 12062143Sarchie /* Upgrade to exclusive lock, this might block */ 12162143Sarchie VOP_LOCK(vp, LK_UPGRADE | LK_NOPAUSE, td); 12262143Sarchie } else 12362143Sarchie upgraded = 0; 12462143Sarchie 12562143Sarchie 12662143Sarchie /* Attempt to msync mmap() regions to clean dirty mmap */ 12762143Sarchie VI_LOCK(vp); 12862143Sarchie if ((vp->v_iflag & VI_OBJDIRTY) != 0) { 12962143Sarchie struct vm_object *obj; 13062143Sarchie VI_UNLOCK(vp); 13162143Sarchie if (VOP_GETVOBJECT(vp, &obj) == 0) { 13262143Sarchie VM_OBJECT_LOCK(obj); 13364358Sarchie vm_object_page_clean(obj, 0, 0, OBJPC_SYNC); 13464358Sarchie VM_OBJECT_UNLOCK(obj); 13564358Sarchie } 13664358Sarchie VI_LOCK(vp); 13764358Sarchie } 138123600Sru 13964358Sarchie /* Wait for pending writes to complete */ 14064358Sarchie spl = splbio(); 14164358Sarchie error = bufobj_wwait(&vp->v_bufobj, 0, 0); 14264653Sarchie if (error != 0) { 14364653Sarchie /* XXX: can't happen with a zero timeout ??? */ 144123600Sru splx(spl); 14564653Sarchie VI_UNLOCK(vp); 14664653Sarchie if (upgraded != 0) 14764653Sarchie VOP_LOCK(vp, LK_DOWNGRADE, td); 14864653Sarchie return (error); 14964653Sarchie } 15064653Sarchie /* Flush dirty buffers */ 15164653Sarchie if (bo->bo_dirty.bv_cnt > 0)) { 15264653Sarchie splx(spl); 15364653Sarchie VI_UNLOCK(vp); 15464653Sarchie if ((error = VOP_FSYNC(vp, NOCRED, MNT_WAIT, td)) != 0) { 15564653Sarchie if (upgraded != 0) 15664358Sarchie VOP_LOCK(vp, LK_DOWNGRADE, td); 15764358Sarchie return (error); 15864358Sarchie } 15964358Sarchie VI_LOCK(vp); 16064358Sarchie spl = splbio(); 16164358Sarchie if (bo->bo_numoutput > 0 || 16264358Sarchie bo->bo_dirty.bv_cnt > 0)) 16364653Sarchie panic("ffs_rawread_sync: dirty bufs"); 16464653Sarchie } 16564653Sarchie splx(spl); 16664653Sarchie VI_UNLOCK(vp); 16764653Sarchie if (upgraded != 0) 16864653Sarchie VOP_LOCK(vp, LK_DOWNGRADE, td); 16964653Sarchie } else { 17064358Sarchie splx(spl); 17164358Sarchie VI_UNLOCK(vp); 17264358Sarchie } 17364358Sarchie return 0; 17464358Sarchie} 175141721Sglebius 176141721Sglebius 177141721Sglebiusstatic int 178141721Sglebiusffs_rawread_readahead(struct vnode *vp, 179141721Sglebius caddr_t udata, 180141721Sglebius off_t offset, 181141721Sglebius size_t len, 182141721Sglebius struct thread *td, 183141721Sglebius struct buf *bp, 184141721Sglebius caddr_t sa) 185141721Sglebius{ 186141721Sglebius int error; 187141721Sglebius u_int iolen; 188141721Sglebius off_t blockno; 189141910Sglebius int blockoff; 190141910Sglebius int bsize; 191141910Sglebius struct vnode *dp; 192141910Sglebius int bforwards; 193141910Sglebius struct inode *ip; 194141910Sglebius ufs2_daddr_t blkno; 195141910Sglebius 19662143Sarchie GIANT_REQUIRED; 19762143Sarchie bsize = vp->v_mount->mnt_stat.f_iosize; 19862143Sarchie 19962143Sarchie ip = VTOI(vp); 200129823Sjulian dp = ip->i_devvp; 201129823Sjulian 202129823Sjulian iolen = ((vm_offset_t) udata) & PAGE_MASK; 203129823Sjulian bp->b_bcount = len; 204129823Sjulian if (bp->b_bcount + iolen > bp->b_kvasize) { 205129823Sjulian bp->b_bcount = bp->b_kvasize; 206129823Sjulian if (iolen != 0) 207129823Sjulian bp->b_bcount -= PAGE_SIZE; 208129823Sjulian } 209129823Sjulian bp->b_flags = 0; /* XXX necessary ? */ 210129823Sjulian bp->b_iocmd = BIO_READ; 21162143Sarchie bp->b_iodone = ffs_rawreadwakeup; 21262143Sarchie bp->b_data = udata; 21362143Sarchie bp->b_saveaddr = sa; 21462143Sarchie blockno = offset / bsize; 21562143Sarchie blockoff = (offset % bsize) / DEV_BSIZE; 21662143Sarchie if ((daddr_t) blockno != blockno) { 21762143Sarchie return EINVAL; /* blockno overflow */ 21862143Sarchie } 21962143Sarchie 22062143Sarchie bp->b_lblkno = bp->b_blkno = blockno; 22162143Sarchie 22262143Sarchie error = ufs_bmaparray(vp, bp->b_lblkno, &blkno, NULL, &bforwards, NULL); 22362143Sarchie if (error != 0) 22462143Sarchie return error; 225106933Ssam if (blkno == -1) { 22662143Sarchie 22762143Sarchie /* Fill holes with NULs to preserve semantics */ 22870784Sjulian 229129281Sarchie if (bp->b_bcount + blockoff * DEV_BSIZE > bsize) 23062143Sarchie bp->b_bcount = bsize - blockoff * DEV_BSIZE; 23162143Sarchie bp->b_bufsize = bp->b_bcount; 232129281Sarchie 23362143Sarchie if (vmapbuf(bp) < 0) 234129281Sarchie return EFAULT; 23562143Sarchie 23662143Sarchie if (ticks - PCPU_GET(switchticks) >= hogticks) 23762143Sarchie uio_yield(); 23862143Sarchie bzero(bp->b_data, bp->b_bufsize); 23962143Sarchie 24062143Sarchie /* Mark operation completed (similar to bufdone()) */ 24162143Sarchie 24262143Sarchie bp->b_resid = 0; 24362143Sarchie bp->b_flags |= B_DONE; 244106933Ssam return 0; 24562143Sarchie } 24662143Sarchie bp->b_blkno = blkno + blockoff; 24770784Sjulian bp->b_offset = bp->b_iooffset = (blkno + blockoff) * DEV_BSIZE; 248129281Sarchie 24962143Sarchie if (bp->b_bcount + blockoff * DEV_BSIZE > bsize * (1 + bforwards)) 250129281Sarchie bp->b_bcount = bsize * (1 + bforwards) - blockoff * DEV_BSIZE; 251129281Sarchie bp->b_bufsize = bp->b_bcount; 25262143Sarchie bp->b_dev = dp->v_rdev; 25362143Sarchie 25462143Sarchie if (vmapbuf(bp) < 0) 255129281Sarchie return EFAULT; 25662143Sarchie 25762143Sarchie if (dp->v_type == VCHR) 25862143Sarchie (void) VOP_SPECSTRATEGY(dp, bp); 25962143Sarchie else 26062143Sarchie (void) VOP_STRATEGY(dp, bp); 26162143Sarchie return 0; 26262143Sarchie} 26362143Sarchie 26462143Sarchie 26562143Sarchiestatic int 26670784Sjulianffs_rawread_main(struct vnode *vp, 26762143Sarchie struct uio *uio) 26862143Sarchie{ 26962143Sarchie int error, nerror; 27062143Sarchie struct buf *bp, *nbp, *tbp; 27162143Sarchie caddr_t sa, nsa, tsa; 27262143Sarchie u_int iolen; 27362143Sarchie int spl; 27470700Sjulian caddr_t udata; 27562143Sarchie long resid; 27662143Sarchie off_t offset; 27762143Sarchie struct thread *td; 27862143Sarchie 27962143Sarchie GIANT_REQUIRED; 28062143Sarchie td = uio->uio_td ? uio->uio_td : curthread; 28162143Sarchie udata = uio->uio_iov->iov_base; 28262143Sarchie resid = uio->uio_resid; 28362143Sarchie offset = uio->uio_offset; 28462143Sarchie 28562143Sarchie /* 28662143Sarchie * keep the process from being swapped 28762143Sarchie */ 28862143Sarchie PHOLD(td->td_proc); 28987599Sobrien 29062143Sarchie error = 0; 29162143Sarchie nerror = 0; 292121816Sbrooks 29362143Sarchie bp = NULL; 29462143Sarchie nbp = NULL; 29562143Sarchie sa = NULL; 29662143Sarchie nsa = NULL; 29768876Sdwmalone 29862143Sarchie while (resid > 0) { 29962143Sarchie 300121816Sbrooks if (bp == NULL) { /* Setup first read */ 30170784Sjulian /* XXX: Leave some bufs for swap */ 30262143Sarchie bp = getpbuf(&ffsrawbufcnt); 30362143Sarchie sa = bp->b_data; 30470784Sjulian bp->b_vp = vp; 30562143Sarchie error = ffs_rawread_readahead(vp, udata, offset, 306132780Skan resid, td, bp, sa); 30764358Sarchie if (error != 0) 30890249Sarchie break; 30962143Sarchie 31062143Sarchie if (resid > bp->b_bufsize) { /* Setup fist readahead */ 311121816Sbrooks /* XXX: Leave bufs for swap */ 31262143Sarchie if (rawreadahead != 0) 313121816Sbrooks nbp = trypbuf(&ffsrawbufcnt); 31462143Sarchie else 31562143Sarchie nbp = NULL; 31662143Sarchie if (nbp != NULL) { 31762143Sarchie nsa = nbp->b_data; 31862143Sarchie nbp->b_vp = vp; 31971849Sjulian 32062143Sarchie nerror = ffs_rawread_readahead(vp, 32162143Sarchie udata + 32262143Sarchie bp->b_bufsize, 32362143Sarchie offset + 32462143Sarchie bp->b_bufsize, 32571849Sjulian resid - 32662143Sarchie bp->b_bufsize, 32771849Sjulian td, 32871849Sjulian nbp, 32971849Sjulian nsa); 33071849Sjulian if (nerror) { 33171849Sjulian relpbuf(nbp, &ffsrawbufcnt); 33271849Sjulian nbp = NULL; 333132780Skan } 33471849Sjulian } 33571849Sjulian } 33662143Sarchie } 33762143Sarchie 338139903Sglebius spl = splbio(); 339139903Sglebius bwait(bp, PRIBIO, "rawrd"); 340139903Sglebius splx(spl); 341139903Sglebius 342139903Sglebius vunmapbuf(bp); 343139903Sglebius 344139903Sglebius iolen = bp->b_bcount - bp->b_resid; 345139903Sglebius if (iolen == 0 && (bp->b_ioflags & BIO_ERROR) == 0) { 346139903Sglebius nerror = 0; /* Ignore possible beyond EOF error */ 347139903Sglebius break; /* EOF */ 348139903Sglebius } 349139903Sglebius 350139903Sglebius if ((bp->b_ioflags & BIO_ERROR) != 0) { 351139903Sglebius error = bp->b_error; 352139903Sglebius break; 353139903Sglebius } 354139903Sglebius resid -= iolen; 355139903Sglebius udata += iolen; 356139903Sglebius offset += iolen; 357139903Sglebius if (iolen < bp->b_bufsize) { 358139903Sglebius /* Incomplete read. Try to read remaining part */ 359139903Sglebius error = ffs_rawread_readahead(vp, 360139903Sglebius udata, 361139903Sglebius offset, 362139903Sglebius bp->b_bufsize - iolen, 363139903Sglebius td, 364139903Sglebius bp, 36562143Sarchie sa); 36662143Sarchie if (error != 0) 36762143Sarchie break; 36862143Sarchie } else if (nbp != NULL) { /* Complete read with readahead */ 36962143Sarchie 37062143Sarchie tbp = bp; 37162143Sarchie bp = nbp; 37262143Sarchie nbp = tbp; 37362143Sarchie 37462143Sarchie tsa = sa; 37570700Sjulian sa = nsa; 37662143Sarchie nsa = tsa; 37762143Sarchie 37862143Sarchie if (resid <= bp->b_bufsize) { /* No more readaheads */ 37962143Sarchie relpbuf(nbp, &ffsrawbufcnt); 38062143Sarchie nbp = NULL; 38162143Sarchie } else { /* Setup next readahead */ 38262143Sarchie nerror = ffs_rawread_readahead(vp, 38362143Sarchie udata + 38462143Sarchie bp->b_bufsize, 38562143Sarchie offset + 38670784Sjulian bp->b_bufsize, 38762143Sarchie resid - 38862143Sarchie bp->b_bufsize, 38962143Sarchie td, 39062143Sarchie nbp, 39162143Sarchie nsa); 39262143Sarchie if (nerror != 0) { 39362143Sarchie relpbuf(nbp, &ffsrawbufcnt); 39462143Sarchie nbp = NULL; 39562143Sarchie } 396129281Sarchie } 39762143Sarchie } else if (nerror != 0) {/* Deferred Readahead error */ 398129281Sarchie break; 399129281Sarchie } else if (resid > 0) { /* More to read, no readahead */ 400129281Sarchie error = ffs_rawread_readahead(vp, udata, offset, 40162143Sarchie resid, td, bp, sa); 40262143Sarchie if (error != 0) 40362143Sarchie break; 40462143Sarchie } 40562143Sarchie } 40662143Sarchie 40790249Sarchie if (bp != NULL) 40890249Sarchie relpbuf(bp, &ffsrawbufcnt); 40990249Sarchie if (nbp != NULL) { /* Run down readahead buffer */ 41090249Sarchie spl = splbio(); 41162143Sarchie bwait(nbp, PRIBIO, "rawrd"); 41262143Sarchie splx(spl); 41362143Sarchie vunmapbuf(nbp); 41462143Sarchie relpbuf(nbp, &ffsrawbufcnt); 41562143Sarchie } 41662143Sarchie 41769922Sjulian if (error == 0) 41869922Sjulian error = nerror; 41969922Sjulian PRELE(td->td_proc); 42069922Sjulian uio->uio_iov->iov_base = udata; 42169922Sjulian uio->uio_resid = resid; 42269922Sjulian uio->uio_offset = offset; 42369922Sjulian return error; 42470784Sjulian} 42569922Sjulian 42669922Sjulian 42769922Sjulianint 42869922Sjulianffs_rawread(struct vnode *vp, 42962143Sarchie struct uio *uio, 43062143Sarchie int *workdone) 43162143Sarchie{ 43270700Sjulian if (allowrawread != 0 && 43362143Sarchie uio->uio_iovcnt == 1 && 43470784Sjulian uio->uio_segflg == UIO_USERSPACE && 43562143Sarchie uio->uio_resid == uio->uio_iov->iov_len && 43662143Sarchie (((uio->uio_td != NULL) ? uio->uio_td : curthread)->td_pflags & 43770700Sjulian TDP_DEADLKTREAT) == 0) { 43862143Sarchie int secsize; /* Media sector size */ 43970700Sjulian off_t filebytes; /* Bytes left of file */ 44062143Sarchie int blockbytes; /* Bytes left of file in full blocks */ 44162143Sarchie int partialbytes; /* Bytes in last partial block */ 44262143Sarchie int skipbytes; /* Bytes not to read in ffs_rawread */ 44362143Sarchie struct inode *ip; 444141195Sru int error; 44562143Sarchie 44662143Sarchie 44762143Sarchie /* Only handle sector aligned reads */ 44862143Sarchie ip = VTOI(vp); 449141195Sru secsize = ip->i_devvp->v_bufobj.bo_bsize; 45062143Sarchie if ((uio->uio_offset & (secsize - 1)) == 0 && 45162143Sarchie (uio->uio_resid & (secsize - 1)) == 0) { 45262143Sarchie 45362143Sarchie /* Sync dirty pages and buffers if needed */ 45462143Sarchie error = ffs_rawread_sync(vp, 45562143Sarchie (uio->uio_td != NULL) ? 45662143Sarchie uio->uio_td : curthread); 45762143Sarchie if (error != 0) 45862143Sarchie return error; 45964358Sarchie 46064358Sarchie /* Check for end of file */ 46164358Sarchie if (ip->i_size > uio->uio_offset) { 46264358Sarchie filebytes = ip->i_size - uio->uio_offset; 46364358Sarchie 46464358Sarchie /* No special eof handling needed ? */ 465147256Sbrooks if (uio->uio_resid <= filebytes) { 46664358Sarchie *workdone = 1; 46764358Sarchie return ffs_rawread_main(vp, uio); 46864653Sarchie } 46964653Sarchie 47064653Sarchie partialbytes = ((unsigned int) ip->i_size) % 47164653Sarchie ip->i_fs->fs_bsize; 47264653Sarchie blockbytes = (int) filebytes - partialbytes; 47364653Sarchie if (blockbytes > 0) { 47464653Sarchie skipbytes = uio->uio_resid - 47564653Sarchie blockbytes; 47664653Sarchie uio->uio_resid = blockbytes; 47764653Sarchie error = ffs_rawread_main(vp, uio); 47864653Sarchie uio->uio_resid += skipbytes; 47964653Sarchie if (error != 0) 48064653Sarchie return error; 48164653Sarchie /* Read remaining part using buffer */ 48264653Sarchie } 48364653Sarchie } 48464653Sarchie } 48564653Sarchie } 48664358Sarchie *workdone = 0; 48764358Sarchie return 0; 48864358Sarchie} 48964358Sarchie 49064358Sarchie 49164358Sarchiestatic void 49264358Sarchieffs_rawreadwakeup(struct buf *bp) 49364358Sarchie{ 49464358Sarchie bdone(bp); 49564358Sarchie} 49664358Sarchie