|
@@ -3488,37 +3488,16 @@ static void btrfs_end_empty_barrier(struct bio *bio)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * trigger flushes for one the devices. If you pass wait == 0, the flushes are
|
|
|
- * sent down. With wait == 1, it waits for the previous flush.
|
|
|
- *
|
|
|
- * any device where the flush fails with eopnotsupp are flagged as not-barrier
|
|
|
- * capable
|
|
|
+ * Submit a flush request to the device if it supports it. Error handling is
|
|
|
+ * done in the waiting counterpart.
|
|
|
*/
|
|
|
-static int write_dev_flush(struct btrfs_device *device, int wait)
|
|
|
+static void write_dev_flush(struct btrfs_device *device)
|
|
|
{
|
|
|
struct request_queue *q = bdev_get_queue(device->bdev);
|
|
|
struct bio *bio;
|
|
|
- int ret = 0;
|
|
|
|
|
|
if (!test_bit(QUEUE_FLAG_WC, &q->queue_flags))
|
|
|
- return 0;
|
|
|
-
|
|
|
- if (wait) {
|
|
|
- bio = device->flush_bio;
|
|
|
- wait_for_completion(&device->flush_wait);
|
|
|
-
|
|
|
- if (bio->bi_error) {
|
|
|
- ret = bio->bi_error;
|
|
|
- btrfs_dev_stat_inc_and_print(device,
|
|
|
- BTRFS_DEV_STAT_FLUSH_ERRS);
|
|
|
- }
|
|
|
-
|
|
|
- /* drop the reference from the wait == 0 run */
|
|
|
- bio_put(bio);
|
|
|
- device->flush_bio = NULL;
|
|
|
-
|
|
|
- return ret;
|
|
|
- }
|
|
|
+ return;
|
|
|
|
|
|
/*
|
|
|
* one reference for us, and we leave it for the
|
|
@@ -3535,8 +3514,32 @@ static int write_dev_flush(struct btrfs_device *device, int wait)
|
|
|
|
|
|
bio_get(bio);
|
|
|
btrfsic_submit_bio(bio);
|
|
|
+}
|
|
|
|
|
|
- return 0;
|
|
|
+/*
|
|
|
+ * If the flush bio has been submitted by write_dev_flush, wait for it.
|
|
|
+ */
|
|
|
+static int wait_dev_flush(struct btrfs_device *device)
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+ struct bio *bio = device->flush_bio;
|
|
|
+
|
|
|
+ if (!bio)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ wait_for_completion(&device->flush_wait);
|
|
|
+
|
|
|
+ if (bio->bi_error) {
|
|
|
+ ret = bio->bi_error;
|
|
|
+ btrfs_dev_stat_inc_and_print(device,
|
|
|
+ BTRFS_DEV_STAT_FLUSH_ERRS);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* drop the reference from the wait == 0 run */
|
|
|
+ bio_put(bio);
|
|
|
+ device->flush_bio = NULL;
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int check_barrier_error(struct btrfs_fs_devices *fsdevs)
|
|
@@ -3577,7 +3580,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
|
|
|
if (!dev->in_fs_metadata || !dev->writeable)
|
|
|
continue;
|
|
|
|
|
|
- write_dev_flush(dev, 0);
|
|
|
+ write_dev_flush(dev);
|
|
|
dev->last_flush_error = 0;
|
|
|
}
|
|
|
|
|
@@ -3592,7 +3595,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
|
|
|
if (!dev->in_fs_metadata || !dev->writeable)
|
|
|
continue;
|
|
|
|
|
|
- ret = write_dev_flush(dev, 1);
|
|
|
+ ret = wait_dev_flush(dev);
|
|
|
if (ret) {
|
|
|
dev->last_flush_error = ret;
|
|
|
errors_wait++;
|