On Tue, May 16, 2017 at 05:39:14PM +0800, Anand Jain wrote:
> Signed-off-by: Anand Jain <anand.j...@oracle.com>

An explanation on why things are changed is entirely missing here..

> ---
>  fs/btrfs/disk-io.c | 108 
> ++++++++++++++++-------------------------------------
>  fs/btrfs/volumes.h |   2 +-
>  2 files changed, 33 insertions(+), 77 deletions(-)
> 
> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> index 8685d67185d0..f059f9bdbbd7 100644
> --- a/fs/btrfs/disk-io.c
> +++ b/fs/btrfs/disk-io.c
> @@ -3478,121 +3478,77 @@ static int write_dev_supers(struct btrfs_device 
> *device,
>  }
>  
>  /*
> - * endio for the write_dev_flush, this will wake anyone waiting
> + * endio for blkdev_issues_flush_no_wait, this will wake anyone waiting
>   * for the barrier when it is done
>   */
>  static void btrfs_end_empty_barrier(struct bio *bio)
>  {
> -     if (bio->bi_private)
> -             complete(bio->bi_private);
> +     struct btrfs_device *device;
> +
> +     device = container_of(bio->bi_private, struct btrfs_device,
> +                                             flush_wait);
> +
> +     device->last_flush_error = bio->bi_error;
> +     complete(&device->flush_wait);
> +
>       bio_put(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
> - */
> -static int write_dev_flush(struct btrfs_device *device, int wait)
> +static void write_dev_flush(struct btrfs_device *device)
>  {
> +     int ret;
>       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;
> -             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;
> -     }
> -
> -     /*
> -      * one reference for us, and we leave it for the
> -      * caller
> -      */
> -     device->flush_bio = NULL;
> -     bio = btrfs_io_bio_alloc(GFP_NOFS, 0);
> -     if (!bio)
> -             return -ENOMEM;
> -
> -     bio->bi_end_io = btrfs_end_empty_barrier;
> -     bio->bi_bdev = device->bdev;
> -     bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
> -     init_completion(&device->flush_wait);
> -     bio->bi_private = &device->flush_wait;
> -     device->flush_bio = bio;
> -
> -     bio_get(bio);
> -     btrfsic_submit_bio(bio);
> +             return;
>  
> -     return 0;
> +     ret = blkdev_issue_flush_no_wait(device->bdev, GFP_NOFS,
> +             btrfs_end_empty_barrier, &device->flush_wait);
> +     if (ret)
> +             device->last_flush_error = ret;
> +     else
> +             device->last_flush_error = -1;
>  }
>  
>  /*
> - * send an empty flush down to each device in parallel,
> - * then wait for them
> + * send flush down to each device in parallel, then wait for them.
>   */
>  static int barrier_all_devices(struct btrfs_fs_info *info)
>  {
>       struct list_head *head;
>       struct btrfs_device *dev;
> -     int errors_send = 0;
>       int errors_wait = 0;
> -     int ret;
>  
>       /* send down all the barriers */
>       head = &info->fs_devices->devices;
>       list_for_each_entry_rcu(dev, head, dev_list) {
> +             dev->last_flush_error = 0;
>               if (dev->missing)
>                       continue;
> +
> +             if (!dev->in_fs_metadata || !dev->writeable)
> +                     continue;
> +
>               if (!dev->bdev) {
> -                     errors_send++;
> +                     dev->last_flush_error = -ENXIO;
>                       continue;
>               }
> -             if (!dev->in_fs_metadata || !dev->writeable)
> -                     continue;
>  
> -             ret = write_dev_flush(dev, 0);
> -             if (ret)
> -                     errors_send++;
> +             write_dev_flush(dev);
>       }
>  
>       /* wait for all the barriers */
>       list_for_each_entry_rcu(dev, head, dev_list) {
> -             if (dev->missing)
> -                     continue;
> -             if (!dev->bdev) {
> -                     errors_wait++;
> -                     continue;
> -             }
> -             if (!dev->in_fs_metadata || !dev->writeable)
> -                     continue;
> +             if (dev->last_flush_error == -1)
> +                     wait_for_completion(&dev->flush_wait);
>  
> -             ret = write_dev_flush(dev, 1);
> -             if (ret)
> +             if (dev->last_flush_error)
>                       errors_wait++;
>       }
> -     if (errors_send > info->num_tolerated_disk_barrier_failures ||
> -         errors_wait > info->num_tolerated_disk_barrier_failures)
> +
> +     if (errors_wait > info->num_tolerated_disk_barrier_failures)
>               return -EIO;
> +
>       return 0;
>  }
>  
> diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
> index c7d0fbc915ca..27af3a227bfb 100644
> --- a/fs/btrfs/volumes.h
> +++ b/fs/btrfs/volumes.h
> @@ -123,8 +123,8 @@ struct btrfs_device {
>       struct list_head resized_list;
>  
>       /* for sending down flush barriers */
> -     struct bio *flush_bio;
>       struct completion flush_wait;
> +     int last_flush_error;
>  
>       /* per-device scrub information */
>       struct scrub_ctx *scrub_device;
> -- 
> 2.10.0
> 
---end quoted text---
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to