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;
next prev parent 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).