summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/geom/geom.h1
-rw-r--r--sys/geom/geom_io.c30
-rw-r--r--sys/kern/subr_disk.c1
-rw-r--r--sys/sys/bio.h1
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 */
OpenPOWER on IntegriCloud