From d5cc90945161b6ca3448116aa23c9ae0b75a6e94 Mon Sep 17 00:00:00 2001 From: pjd Date: Tue, 31 Oct 2006 21:11:21 +0000 Subject: Add a new I/O request - BIO_FLUSH, which basically tells providers below to flush their caches. For now will mostly be used by disks to flush their write cache. Sponsored by: home.pl --- sys/geom/geom.h | 1 + sys/geom/geom_io.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'sys/geom') diff --git a/sys/geom/geom.h b/sys/geom/geom.h index 5b55624..4d7c5b8 100644 --- a/sys/geom/geom.h +++ b/sys/geom/geom.h @@ -268,6 +268,7 @@ struct bio * g_duplicate_bio(struct bio *); void g_destroy_bio(struct bio *); void g_io_deliver(struct bio *bp, int error); int g_io_getattr(const char *attr, struct g_consumer *cp, int *len, void *ptr); +int g_io_flush(struct g_consumer *cp); void g_io_request(struct bio *bp, struct g_consumer *cp); struct bio *g_new_bio(void); struct bio *g_alloc_bio(void); diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c index c95dbf8..18cedcd 100644 --- a/sys/geom/geom_io.c +++ b/sys/geom/geom_io.c @@ -244,6 +244,26 @@ g_io_getattr(const char *attr, struct g_consumer *cp, int *len, void *ptr) return (error); } +int +g_io_flush(struct g_consumer *cp) +{ + struct bio *bp; + int error; + + g_trace(G_T_BIO, "bio_flush(%s)", cp->provider->name); + bp = g_alloc_bio(); + bp->bio_cmd = BIO_FLUSH; + bp->bio_done = NULL; + bp->bio_attribute = NULL; + bp->bio_offset = cp->provider->mediasize; + bp->bio_length = 0; + bp->bio_data = NULL; + g_io_request(bp, cp); + error = biowait(bp, "gflush"); + g_destroy_bio(bp); + return (error); +} + static int g_io_check(struct bio *bp) { @@ -262,6 +282,7 @@ g_io_check(struct bio *bp) break; case BIO_WRITE: case BIO_DELETE: + case BIO_FLUSH: if (cp->acw == 0) return (EPERM); break; @@ -304,7 +325,6 @@ g_io_request(struct bio *bp, struct g_consumer *cp) KASSERT(cp != NULL, ("NULL cp in g_io_request")); KASSERT(bp != NULL, ("NULL bp in g_io_request")); - KASSERT(bp->bio_data != NULL, ("NULL bp->data in g_io_request")); pp = cp->provider; KASSERT(pp != NULL, ("consumer not attached in g_io_request")); #ifdef DIAGNOSTIC @@ -323,6 +343,10 @@ g_io_request(struct bio *bp, struct g_consumer *cp) bp->_bio_cflags = bp->bio_cflags; #endif + if (bp->bio_cmd & (BIO_READ|BIO_WRITE|BIO_DELETE|BIO_GETATTR)) { + KASSERT(bp->bio_data != NULL, + ("NULL bp->data in g_io_request")); + } if (bp->bio_cmd & (BIO_READ|BIO_WRITE|BIO_DELETE)) { KASSERT(bp->bio_offset % cp->provider->sectorsize == 0, ("wrong offset %jd for sectorsize %u", @@ -632,6 +656,10 @@ g_print_bio(struct bio *bp) cmd = "GETATTR"; printf("%s[%s(attr=%s)]", pname, cmd, bp->bio_attribute); return; + case BIO_FLUSH: + cmd = "FLUSH"; + printf("%s[%s]", pname, cmd); + return; case BIO_READ: cmd = "READ"; case BIO_WRITE: -- cgit v1.1