summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/man/man9/disk.94
-rw-r--r--sys/geom/geom_disk.c22
-rw-r--r--sys/geom/geom_disk.h1
3 files changed, 25 insertions, 2 deletions
diff --git a/share/man/man9/disk.9 b/share/man/man9/disk.9
index d8d446b..d071613 100644
--- a/share/man/man9/disk.9
+++ b/share/man/man9/disk.9
@@ -94,8 +94,10 @@ Currently supported flags are
(maintained by device driver),
.Dv DISKFLAG_OPEN
(maintained by storage framework),
-and
.Dv DISKFLAG_CANDELETE
+(maintained by device driver),
+and
+.Dv DISKFLAG_CANFLUSHCACHE
(maintained by device driver).
.It Vt "const char *" Va d_name
Holds the name of the storage device class, e.g.,
diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c
index 6115106..1a65d89 100644
--- a/sys/geom/geom_disk.c
+++ b/sys/geom/geom_disk.c
@@ -202,8 +202,10 @@ g_disk_done(struct bio *bp)
if (bp2->bio_error == 0)
bp2->bio_error = bp->bio_error;
bp2->bio_completed += bp->bio_completed;
- if ((dp = bp2->bio_to->geom->softc))
+ if ((bp->bio_cmd & (BIO_READ|BIO_WRITE|BIO_DELETE)) &&
+ (dp = bp2->bio_to->geom->softc)) {
devstat_end_transaction_bio(dp->d_devstat, bp);
+ }
g_destroy_bio(bp);
bp2->bio_inbed++;
if (bp2->bio_children == bp2->bio_inbed) {
@@ -304,6 +306,24 @@ g_disk_start(struct bio *bp)
else
error = ENOIOCTL;
break;
+ case BIO_FLUSH:
+ g_trace(G_T_TOPOLOGY, "g_disk_flushcache(%s)",
+ bp->bio_to->name);
+ if (!(dp->d_flags & DISKFLAG_CANFLUSHCACHE)) {
+ g_io_deliver(bp, ENODEV);
+ return;
+ }
+ bp2 = g_clone_bio(bp);
+ if (bp2 == NULL) {
+ g_io_deliver(bp, ENOMEM);
+ return;
+ }
+ bp2->bio_done = g_disk_done;
+ bp2->bio_disk = dp;
+ g_disk_lock_giant(dp);
+ dp->d_strategy(bp2);
+ g_disk_unlock_giant(dp);
+ break;
default:
error = EOPNOTSUPP;
break;
diff --git a/sys/geom/geom_disk.h b/sys/geom/geom_disk.h
index 23719bf..9e8b1ef 100644
--- a/sys/geom/geom_disk.h
+++ b/sys/geom/geom_disk.h
@@ -91,6 +91,7 @@ struct disk {
#define DISKFLAG_NEEDSGIANT 0x1
#define DISKFLAG_OPEN 0x2
#define DISKFLAG_CANDELETE 0x4
+#define DISKFLAG_CANFLUSHCACHE 0x8
struct disk *disk_alloc(void);
void disk_create(struct disk *disk, int version);
OpenPOWER on IntegriCloud