Merge tag 'for-linus-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
[linux-2.6-microblaze.git] / fs / xfs / xfs_bio_io.c
index 17f36db..667e297 100644 (file)
@@ -9,6 +9,41 @@ static inline unsigned int bio_max_vecs(unsigned int count)
        return bio_max_segs(howmany(count, PAGE_SIZE));
 }
 
+static void
+xfs_flush_bdev_async_endio(
+       struct bio      *bio)
+{
+       complete(bio->bi_private);
+}
+
+/*
+ * Submit a request for an async cache flush to run. If the request queue does
+ * not require flush operations, just skip it altogether. If the caller needs
+ * to wait for the flush completion at a later point in time, they must supply a
+ * valid completion. This will be signalled when the flush completes.  The
+ * caller never sees the bio that is issued here.
+ */
+void
+xfs_flush_bdev_async(
+       struct bio              *bio,
+       struct block_device     *bdev,
+       struct completion       *done)
+{
+       struct request_queue    *q = bdev->bd_disk->queue;
+
+       if (!test_bit(QUEUE_FLAG_WC, &q->queue_flags)) {
+               complete(done);
+               return;
+       }
+
+       bio_init(bio, NULL, 0);
+       bio_set_dev(bio, bdev);
+       bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC;
+       bio->bi_private = done;
+       bio->bi_end_io = xfs_flush_bdev_async_endio;
+
+       submit_bio(bio);
+}
 int
 xfs_rw_bdev(
        struct block_device     *bdev,