summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/geom/geom_disk.c')
-rw-r--r--sys/geom/geom_disk.c22
1 files changed, 21 insertions, 1 deletions
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;
OpenPOWER on IntegriCloud