This is what physio() is for.
This commit is contained in:
parent
0a6d915b83
commit
c0e128ac74
@ -1,106 +0,0 @@
|
||||
/* $NetBSD: raw_diskio.c,v 1.4 1994/10/26 02:33:01 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993 Paul Mackerras.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, provided that the above copyright
|
||||
* notice appears in all copies. This software is provided without any
|
||||
* warranty, express or implied. The author makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/uio.h>
|
||||
#include <vm/vm.h>
|
||||
|
||||
int rawio_piece();
|
||||
|
||||
int
|
||||
raw_disk_io(int dev, struct uio *uio, int blocksize)
|
||||
{
|
||||
struct buf *bp;
|
||||
int err, ioc;
|
||||
struct iovec *iov;
|
||||
|
||||
if( uio->uio_offset % blocksize != 0 )
|
||||
return EINVAL;
|
||||
|
||||
MALLOC(bp, struct buf *, sizeof(struct buf), M_TEMP, M_WAITOK);
|
||||
bzero(bp, sizeof(*bp));
|
||||
bp->b_flags = B_BUSY | B_PHYS | B_RAW;
|
||||
if( uio->uio_rw == UIO_READ )
|
||||
bp->b_flags |= B_READ;
|
||||
bp->b_dev = dev;
|
||||
bp->b_proc = curproc;
|
||||
|
||||
while (uio->uio_resid != 0) {
|
||||
iov = uio->uio_iov;
|
||||
if (iov->iov_len != 0) {
|
||||
err = rawio_piece(bp, blocksize, uio, iov);
|
||||
if (err != 0 || iov->iov_len != 0)
|
||||
break;
|
||||
}
|
||||
++uio->uio_iov;
|
||||
--uio->uio_iovcnt;
|
||||
}
|
||||
|
||||
FREE(bp, M_TEMP);
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
rawio_piece(struct buf *bp, int blocksize,
|
||||
struct uio *uio, struct iovec *iov)
|
||||
{
|
||||
int s, todo, done;
|
||||
vm_offset_t va;
|
||||
|
||||
if (iov->iov_len % blocksize != 0)
|
||||
return EINVAL;
|
||||
if (!useracc(iov->iov_base, iov->iov_len,
|
||||
(uio->uio_rw == UIO_READ? B_WRITE: B_READ)))
|
||||
return EFAULT;
|
||||
|
||||
while( iov->iov_len != 0 ){
|
||||
bp->b_data = iov->iov_base;
|
||||
bp->b_flags &= ~B_DONE;
|
||||
bp->b_bufsize = iov->iov_len;
|
||||
bp->b_bcount = todo = min(iov->iov_len, MAXPHYS);
|
||||
bp->b_blkno = uio->uio_offset / blocksize;
|
||||
|
||||
++bp->b_proc->p_holdcnt;
|
||||
vslock(iov->iov_base, todo);
|
||||
vmapbuf(bp);
|
||||
|
||||
cdevsw[major(bp->b_dev)].d_strategy(bp);
|
||||
s = splbio();
|
||||
while( (bp->b_flags & B_DONE) == 0 )
|
||||
tsleep((caddr_t) bp, PRIBIO + 1, "physio", 0);
|
||||
splx(s);
|
||||
|
||||
vunmapbuf(bp);
|
||||
vsunlock(iov->iov_base, todo, uio->uio_rw == UIO_READ);
|
||||
--bp->b_proc->p_holdcnt;
|
||||
|
||||
done = todo - bp->b_resid;
|
||||
iov->iov_len -= done;
|
||||
iov->iov_base += done;
|
||||
uio->uio_offset += done;
|
||||
uio->uio_resid -= done;
|
||||
|
||||
if ((bp->b_flags & B_ERROR) != 0 || bp->b_error != 0
|
||||
|| bp->b_resid != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((bp->b_flags & B_ERROR) != 0 && bp->b_error == 0)
|
||||
bp->b_error = EIO;
|
||||
return bp->b_error;
|
||||
}
|
Loading…
Reference in New Issue
Block a user