summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2006-10-31 21:11:21 +0000
committerpjd <pjd@FreeBSD.org>2006-10-31 21:11:21 +0000
commitd5cc90945161b6ca3448116aa23c9ae0b75a6e94 (patch)
treebc3a2953fbf55d1341923bd813f3f8dd4551b7bd /sys/geom
parent60bc6ceecb65e600a49d7751c905d60ad41a380b (diff)
downloadFreeBSD-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
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/geom.h1
-rw-r--r--sys/geom/geom_io.c30
2 files changed, 30 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:
OpenPOWER on IntegriCloud