All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@infradead.org>
To: Anand Jain <anand.jain@oracle.com>
Cc: linux-btrfs@vger.kernel.org, linux-block@vger.kernel.org,
	dsterba@suse.cz
Subject: Re: [PATCH 2/2] btrfs: Use blkdev_issue_flush_no_wait()
Date: Tue, 16 May 2017 05:00:15 -0700	[thread overview]
Message-ID: <20170516120015.GB18649@infradead.org> (raw)
In-Reply-To: <20170516093914.16035-3-anand.jain@oracle.com>

On Tue, May 16, 2017 at 05:39:14PM +0800, Anand Jain wrote:
> Signed-off-by: Anand Jain <anand.jain@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---

  reply	other threads:[~2017-05-16 12:00 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-16  9:39 [RFC PATCH 0/2] Introduce blkdev_issue_flush_no_wait() Anand Jain
2017-05-16  9:39 ` [PATCH 1/2] block: " Anand Jain
2017-05-16 11:56   ` Christoph Hellwig
2017-05-18  9:31     ` Anand Jain
2017-05-21  7:09       ` Christoph Hellwig
2017-05-24  8:42         ` Anand Jain
2017-05-16  9:39 ` [PATCH 2/2] btrfs: Use blkdev_issue_flush_no_wait() Anand Jain
2017-05-16 12:00   ` Christoph Hellwig [this message]
2017-05-16 14:07 ` [RFC PATCH 0/2] Introduce blkdev_issue_flush_no_wait() Bart Van Assche
2017-05-16 14:07   ` Bart Van Assche
2017-05-17 17:14   ` David Sterba
2017-05-18  9:31     ` Anand Jain
2017-05-18  9:27   ` Anand Jain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170516120015.GB18649@infradead.org \
    --to=hch@infradead.org \
    --cc=anand.jain@oracle.com \
    --cc=dsterba@suse.cz \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.