Skip to content
Snippets Groups Projects
Commit 19ef05ac authored by Christoph Hellwig's avatar Christoph Hellwig
Browse files

use the buffercache for block device I/O

parent 9ec66701
No related branches found
No related tags found
No related merge requests found
......@@ -102,6 +102,7 @@ fs = fs/fs.o bootfs.o
fs += fs/vfs/main.o \
fs/vfs/kern_physio.o \
fs/vfs/subr_uio.o \
fs/vfs/vfs_bdev.o \
fs/vfs/vfs_bio.o \
fs/vfs/vfs_conf.o \
fs/vfs/vfs_lookup.o \
......
......@@ -48,14 +48,25 @@ struct ramdisk_softc {
static pthread_t ramdisk_thread;
static int
ramdisk_rdwr(struct device *dev, struct uio *uio, int ioflags)
ramdisk_read(struct device *dev, struct uio *uio, int ioflags)
{
struct ramdisk_softc *sc = dev->private_data;
if (uio->uio_offset + uio->uio_resid > sc->size)
return EIO;
return physio(dev, uio, ioflags);
return bdev_read(dev, uio, ioflags);
}
static int
ramdisk_write(struct device *dev, struct uio *uio, int ioflags)
{
struct ramdisk_softc *sc = dev->private_data;
if (uio->uio_offset + uio->uio_resid > sc->size)
return EIO;
return bdev_write(dev, uio, ioflags);
}
static void
......@@ -91,8 +102,8 @@ ramdisk_strategy(struct bio *bio)
static struct devops ramdisk_devops = {
.open = no_open,
.close = no_close,
.read = ramdisk_rdwr,
.write = ramdisk_rdwr,
.read = ramdisk_read,
.write = ramdisk_write,
.ioctl = no_ioctl,
.devctl = no_devctl,
.strategy = ramdisk_strategy,
......
......@@ -46,7 +46,7 @@ virtio_blk_strategy(struct bio *bio)
}
static int
virtio_blk_rdwr(struct device *dev, struct uio *uio, int ioflags)
virtio_blk_read(struct device *dev, struct uio *uio, int ioflags)
{
struct virtio_blk_priv *prv =
reinterpret_cast<struct virtio_blk_priv*>(dev->private_data);
......@@ -54,14 +54,26 @@ virtio_blk_rdwr(struct device *dev, struct uio *uio, int ioflags)
if (uio->uio_offset + uio->uio_resid > prv->drv->size())
return EIO;
return physio(dev, uio, ioflags);
return bdev_read(dev, uio, ioflags);
}
static int
virtio_blk_write(struct device *dev, struct uio *uio, int ioflags)
{
struct virtio_blk_priv *prv =
reinterpret_cast<struct virtio_blk_priv*>(dev->private_data);
if (uio->uio_offset + uio->uio_resid > prv->drv->size())
return EIO;
return bdev_write(dev, uio, ioflags);
}
static struct devops virtio_blk_devops = {
.open = no_open,
.close = no_close,
.read = virtio_blk_rdwr,
.write = virtio_blk_rdwr,
.read = virtio_blk_read,
.write = virtio_blk_write,
.ioctl = no_ioctl,
.devctl = no_devctl,
.strategy = virtio_blk_strategy,
......
......@@ -44,52 +44,3 @@ biodone(struct bio *bio)
bio_done(bio);
}
}
int
physio(struct device *dev, struct uio *uio, int ioflags)
{
struct bio *bio;
if (uio->uio_offset < 0)
return EINVAL;
if (uio->uio_resid == 0)
return 0;
while (uio->uio_resid > 0) {
struct iovec *iov = uio->uio_iov;
if (!iov->iov_len)
continue;
bio = alloc_bio();
if (!bio)
return ENOMEM;
if (uio->uio_rw == UIO_READ)
bio->bio_cmd = BIO_READ;
else
bio->bio_cmd = BIO_WRITE;
bio->bio_dev = dev;
bio->bio_data = iov->iov_base;
bio->bio_offset = uio->uio_offset;
bio->bio_bcount = uio->uio_resid;
dev->driver->devops->strategy(bio);
pthread_mutex_lock(&bio->bio_mutex);
while (!(bio->bio_flags & BIO_DONE))
pthread_cond_wait(&bio->bio_wait, &bio->bio_mutex);
pthread_mutex_unlock(&bio->bio_mutex);
destroy_bio(bio);
uio->uio_iov++;
uio->uio_iovcnt--;
uio->uio_resid -= iov->iov_len;
uio->uio_offset += iov->iov_len;
}
return 0;
}
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <osv/device.h>
#include <osv/prex.h>
#include <osv/buf.h>
#include <osv/bio.h>
int
bdev_read(struct device *dev, struct uio *uio, int ioflags)
{
struct buf *bp;
int ret;
assert(uio->uio_rw == UIO_READ);
/*
* These should be handled gracefully, but this gives us the
* best debugging for now.
*/
assert((uio->uio_offset % BSIZE) == 0);
assert((uio->uio_resid % BSIZE) == 0);
if (uio->uio_offset < 0)
return EINVAL;
if (uio->uio_resid == 0)
return 0;
while (uio->uio_resid > 0) {
struct iovec *iov = uio->uio_iov;
if (!iov->iov_len)
continue;
ret = bread(dev, uio->uio_offset >> 9, &bp);
if (ret)
return ret;
ret = uiomove(bp->b_data, BSIZE, uio);
brelse(bp);
if (ret)
return ret;
}
return 0;
}
int
bdev_write(struct device *dev, struct uio *uio, int ioflags)
{
struct buf *bp;
int ret;
assert(uio->uio_rw == UIO_WRITE);
/*
* These should be handled gracefully, but this gives us the
* best debugging for now.
*/
assert((uio->uio_offset % BSIZE) == 0);
assert((uio->uio_resid % BSIZE) == 0);
if (uio->uio_offset < 0)
return EINVAL;
if (uio->uio_resid == 0)
return 0;
while (uio->uio_resid > 0) {
struct iovec *iov = uio->uio_iov;
if (!iov->iov_len)
continue;
bp = getblk(dev, uio->uio_offset >> 9);
ret = uiomove(bp->b_data, BSIZE, uio);
if (ret) {
brelse(bp);
return ret;
}
ret = bwrite(bp);
if (ret)
return ret;
}
return 0;
}
int
physio(struct device *dev, struct uio *uio, int ioflags)
{
struct bio *bio;
if (uio->uio_offset < 0)
return EINVAL;
if (uio->uio_resid == 0)
return 0;
while (uio->uio_resid > 0) {
struct iovec *iov = uio->uio_iov;
if (!iov->iov_len)
continue;
bio = alloc_bio();
if (!bio)
return ENOMEM;
if (uio->uio_rw == UIO_READ)
bio->bio_cmd = BIO_READ;
else
bio->bio_cmd = BIO_WRITE;
bio->bio_dev = dev;
bio->bio_data = iov->iov_base;
bio->bio_offset = uio->uio_offset;
bio->bio_bcount = uio->uio_resid;
dev->driver->devops->strategy(bio);
pthread_mutex_lock(&bio->bio_mutex);
while (!(bio->bio_flags & BIO_DONE))
pthread_cond_wait(&bio->bio_wait, &bio->bio_mutex);
pthread_mutex_unlock(&bio->bio_mutex);
destroy_bio(bio);
uio->uio_iov++;
uio->uio_iovcnt--;
uio->uio_resid -= iov->iov_len;
uio->uio_offset += iov->iov_len;
}
return 0;
}
......@@ -128,6 +128,9 @@ int device_write(struct device *, struct uio *, int);
int device_ioctl(struct device *, u_long, void *);
int device_info(struct devinfo *);
int bdev_read(struct device *dev, struct uio *uio, int ioflags);
int bdev_write(struct device *dev, struct uio *uio, int ioflags);
int enodev(void);
int nullop(void);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment