diff options
author | pjd <pjd@FreeBSD.org> | 2006-10-31 21:11:21 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2006-10-31 21:11:21 +0000 |
commit | d5cc90945161b6ca3448116aa23c9ae0b75a6e94 (patch) | |
tree | bc3a2953fbf55d1341923bd813f3f8dd4551b7bd | |
parent | 60bc6ceecb65e600a49d7751c905d60ad41a380b (diff) | |
download | FreeBSD-src-d5cc90945161b6ca3448116aa23c9ae0b75a6e94.zip FreeBSD-src-d5cc90945161b6ca3448116aa23c9ae0b75a6e94.tar.gz |
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
-rw-r--r-- | sys/geom/geom.h | 1 | ||||
-rw-r--r-- | sys/geom/geom_io.c | 30 | ||||
-rw-r--r-- | sys/kern/subr_disk.c | 1 | ||||
-rw-r--r-- | sys/sys/bio.h | 1 |
4 files changed, 32 insertions, 1 deletions
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: diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index 56bab3e..c8ed9ce 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -43,6 +43,7 @@ disk_err(struct bio *bp, const char *what, int blkdone, int nl) case BIO_WRITE: printf("cmd=write "); break; case BIO_DELETE: printf("cmd=delete "); break; case BIO_GETATTR: printf("cmd=getattr "); break; + case BIO_FLUSH: printf("cmd=flush "); break; default: printf("cmd=%x ", bp->bio_cmd); break; } sn = bp->bio_pblkno; diff --git a/sys/sys/bio.h b/sys/sys/bio.h index 2dbdfb9..3635963 100644 --- a/sys/sys/bio.h +++ b/sys/sys/bio.h @@ -93,6 +93,7 @@ struct bio { #define BIO_WRITE 0x02 #define BIO_DELETE 0x04 #define BIO_GETATTR 0x08 +#define BIO_FLUSH 0x10 #define BIO_CMD0 0x20 /* Available for local hacks */ #define BIO_CMD1 0x40 /* Available for local hacks */ #define BIO_CMD2 0x80 /* Available for local hacks */ |