linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sanidhya Solanki <lkml.page@gmail.com>
To: Qu Wenruo <quwenruo@cn.fujitsu.com>
Cc: linux-btrfs@vger.kernel.org
Subject: Re: [RFC PATCH v0.8 02/14] btrfs-progs: Allow __btrfs_map_block_v2 to remove unrelated stripes
Date: Thu, 20 Oct 2016 05:23:02 -0400	[thread overview]
Message-ID: <20161020052302.0032170a@ad> (raw)
In-Reply-To: <20161017012743.9692-3-quwenruo@cn.fujitsu.com>

On Mon, 17 Oct 2016 09:27:31 +0800
Qu Wenruo <quwenruo@cn.fujitsu.com> wrote:

> For READ, caller normally hopes to get what they request, other than
> full stripe map.
> 
> In this case, we should remove unrelated stripe map, just like the
> following case:
>                32K               96K
>                |<-request range->|
>          0              64k           128K
> RAID0:   |    Data 1    |   Data 2    |
>               disk1         disk2
> Before this patch, we return the full stripe:
> Stripe 0: Logical 0, Physical X, Len 64K, Dev disk1
> Stripe 1: Logical 64k, Physical Y, Len 64K, Dev disk2
> 
> After this patch, we limit the stripe result to the request range:
> Stripe 0: Logical 32K, Physical X+32K, Len 32K, Dev disk1
> Stripe 1: Logical 64k, Physical Y, Len 32K, Dev disk2
> 
> And if it's a RAID5/6 stripe, we just handle it like RAID0, ignoring
> parities.
> 
> This should make caller easier to use.
> 
> Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
> ---
>  volumes.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 102 insertions(+), 1 deletion(-)
> 
> diff --git a/volumes.c b/volumes.c
> index 94f3e42..ba16d19 100644
> --- a/volumes.c
> +++ b/volumes.c
> @@ -1682,6 +1682,107 @@ static int fill_full_map_block(struct map_lookup *map, u64 start, u64 length,
>  	return 0;
>  }
>  
> +static void del_one_stripe(struct btrfs_map_block *map_block, int i)
> +{
> +	int cur_nr = map_block->num_stripes;
> +	int size_left = (cur_nr - 1 - i) * sizeof(struct btrfs_map_stripe);
> +
> +	memmove(&map_block->stripes[i], &map_block->stripes[i + 1], size_left);
> +	map_block->num_stripes--;
> +}
> +
> +static void remove_unrelated_stripes(struct map_lookup *map,
> +				     int rw, u64 start, u64 length,
> +				     struct btrfs_map_block *map_block)
> +{
> +	int i = 0;
> +	/*
> +	 * RAID5/6 write must use full stripe.
> +	 * No need to do anything.
> +	 */
> +	if (map->type & (BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6) &&
> +	    rw == WRITE)
> +		return;

I believe it should be an "or" operation in the loop condition, rather than a
single pipe.

Sanidhya

> +	/*
> +	 * For RAID0/1/10/DUP, whatever read/write, we can remove unrelated
> +	 * stripes without causing anything wrong.
> +	 * RAID5/6 READ is just like RAID0, we don't care parity unless we need
> +	 * to recovery.
> +	 * For recovery, rw should be set to WRITE.
> +	 */
> +	while (i < map_block->num_stripes) {
> +		struct btrfs_map_stripe *stripe;
> +		u64 orig_logical; /* Original stripe logical start */
> +		u64 orig_end; /* Original stripe logical end */
> +
> +		stripe = &map_block->stripes[i];
> +
> +		/*
> +		 * For READ, we don't really care parity
> +		 */
> +		if (stripe->logical == BTRFS_RAID5_P_STRIPE ||
> +		    stripe->logical == BTRFS_RAID6_Q_STRIPE) {
> +			del_one_stripe(map_block, i);
> +			continue;
> +		}
> +		/* Completely unrelated stripe */
> +		if (stripe->logical >= start + length ||
> +		    stripe->logical + stripe->length <= start) {
> +			del_one_stripe(map_block, i);
> +			continue;
> +		}
> +		/* Covered stripe, modify its logical and physical */
> +		orig_logical = stripe->logical;
> +		orig_end = stripe->logical + stripe->length;
> +		if (start + length <= orig_end) {
> +			/*
> +			 * |<--range-->|
> +			 *   |  stripe   |
> +			 * Or
> +			 *     |<range>|
> +			 *   |  stripe   |
> +			 */
> +			stripe->logical = max(orig_logical, start);
> +			stripe->length = start + length;
> +			stripe->physical += stripe->logical - orig_logical;
> +		} else if (start >= orig_logical) {
> +			/*
> +			 *     |<-range--->|
> +			 * |  stripe     |
> +			 * Or
> +			 *     |<range>|
> +			 * |  stripe     |
> +			 */
> +			stripe->logical = start;
> +			stripe->length = min(orig_end, start + length);
> +			stripe->physical += stripe->logical - orig_logical;
> +		}
> +		/*
> +		 * Remaining case:
> +		 * |<----range----->|
> +		 *   | stripe |
> +		 * No need to do any modification
> +		 */
> +		i++;
> +	}
> +
> +	/* Recaculate map_block size */
> +	map_block->start = 0;
> +	map_block->length = 0;
> +	for (i = 0; i < map_block->num_stripes; i++) {
> +		struct btrfs_map_stripe *stripe;
> +
> +		stripe = &map_block->stripes[i];
> +		if (stripe->logical > map_block->start)
> +			map_block->start = stripe->logical;
> +		if (stripe->logical + stripe->length >
> +		    map_block->start + map_block->length)
> +			map_block->length = stripe->logical + stripe->length -
> +					    map_block->start;
> +	}
> +}
> +
>  int __btrfs_map_block_v2(struct btrfs_fs_info *fs_info, int rw, u64 logical,
>  			 u64 length, struct btrfs_map_block **map_ret)
>  {
> @@ -1717,7 +1818,7 @@ int __btrfs_map_block_v2(struct btrfs_fs_info *fs_info, int rw, u64 logical,
>  		free(map_block);
>  		return ret;
>  	}
> -	/* TODO: Remove unrelated map_stripes for READ operation */
> +	remove_unrelated_stripes(map, rw, logical, length, map_block);
>  
>  	*map_ret = map_block;
>  	return 0;


  reply	other threads:[~2016-10-20  9:23 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-17  1:27 [RFC PATCH v0.8 00/14] Offline scrub support, and hint to solve kernel scrub data silent corruption Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 01/14] btrfs-progs: Introduce new btrfs_map_block function which returns more unified result Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 02/14] btrfs-progs: Allow __btrfs_map_block_v2 to remove unrelated stripes Qu Wenruo
2016-10-20  9:23   ` Sanidhya Solanki [this message]
2016-10-20  9:35     ` Qu Wenruo
2016-10-20 10:12       ` Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 03/14] btrfs-progs: check/csum: Introduce function to read out one data csum Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 04/14] btrfs-progs: check/scrub: Introduce structures to support fsck scrub Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 05/14] btrfs-progs: check/scrub: Introduce function to scrub mirror based tree block Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 06/14] btrfs-progs: check/scrub: Introduce function to scrub mirror based data blocks Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 07/14] btrfs-progs: check/scrub: Introduce function to scrub one extent Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 08/14] btrfs-progs: check/scrub: Introduce function to scrub one data stripe Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 09/14] btrfs-progs: check/scrub: Introduce function to verify parities Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 10/14] btrfs-progs: extent-tree: Introduce function to check if there is any extent in given range Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 11/14] btrfs-progs: check/scrub: Introduce function to recover data parity Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 12/14] btrfs-progs: check/scrub: Introduce a function to scrub one full stripe Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 13/14] btrfs-progs: check/scrub: Introduce function to check a whole block group Qu Wenruo
2016-10-17  1:27 ` [RFC PATCH v0.8 14/14] btrfs-progs: fsck: Introduce offline scrub function Qu Wenruo

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=20161020052302.0032170a@ad \
    --to=lkml.page@gmail.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=quwenruo@cn.fujitsu.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).