On Mon, Feb 20, 2017 at 11:54:31AM +0800, Qu Wenruo wrote:
> 
> 
> At 02/18/2017 09:28 AM, Liu Bo wrote:
> > Since DISCARD is not as important as an operation like write, we don't
> > copy it to target device during replace, and it makes __btrfs_map_block
> > less complex.
> 
> Makes sense to me.
> 
> > 
> > Signed-off-by: Liu Bo <[email protected]>
> > ---
> >  fs/btrfs/volumes.c | 306 
> > +++++++++++++++++++++++++++++++++--------------------
> >  1 file changed, 192 insertions(+), 114 deletions(-)
> > 
> > diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> > index c52b0fe..96228f3 100644
> > --- a/fs/btrfs/volumes.c
> > +++ b/fs/btrfs/volumes.c
> > @@ -5294,6 +5294,175 @@ void btrfs_put_bbio(struct btrfs_bio *bbio)
> >             kfree(bbio);
> >  }
> > 
> > +/* can REQ_OP_DISCARD be sent with other REQ like REQ_OP_WRITE? */
> > +/*
> > + * Please note that, discard won't be sent to target device of device
> > + * replace.
> > + */
> > +static int __btrfs_map_block_for_discard(struct btrfs_fs_info *fs_info,
> > +                                    u64 logical, u64 length,
> > +                                    struct btrfs_bio **bbio_ret)
> > +{
> > +   struct extent_map_tree *em_tree = &fs_info->mapping_tree.map_tree;
> > +   struct extent_map *em;
> > +   struct map_lookup *map;
> > +   struct btrfs_bio *bbio;
> > +   u64 offset;
> > +   u64 stripe_nr;
> > +   u64 stripe_nr_end;
> > +   u64 stripe_end_offset;
> > +   u64 stripe_cnt;
> > +   u64 stripe_len;
> > +   u64 stripe_offset;
> > +   u64 num_stripes;
> > +   u32 stripe_index;
> > +   u32 factor = 0;
> > +   u32 sub_stripes = 0;
> > +   u64 stripes_per_dev = 0;
> > +   u32 remaining_stripes = 0;
> > +   u32 last_stripe = 0;
> > +   int ret = 0;
> > +   int i;
> > +
> > +   /* discard always return a bbio */
> > +   ASSERT(bbio_ret);
> > +
> > +   read_lock(&em_tree->lock);
> > +   em = lookup_extent_mapping(em_tree, logical, length);
> > +   read_unlock(&em_tree->lock);
> 
> It seems that get_chunk_map() in previous patch can replace such searching
> and error message.
>

Yeah, I forgot to update with it.

> > +
> > +   if (!em) {
> > +           btrfs_crit(fs_info, "unable to find logical %llu len %llu",
> > +                   logical, length);
> > +           return -EINVAL;
> > +   }
> > +
> > +   if (em->start > logical || em->start + em->len < logical) {
> > +           btrfs_crit(fs_info,
> > +                      "found a bad mapping, wanted %Lu, found %Lu-%Lu",
> > +                      logical, em->start, em->start + em->len);
> > +           free_extent_map(em);
> > +           return -EINVAL;
> > +   }
> > +
> > +   map = em->map_lookup;
> > +   /* we don't discard raid56 yet */
> > +   if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
> > +           ret = -EOPNOTSUPP;
> > +           goto out;
> > +   }
> > +
> > +   offset = logical - em->start;
> > +   length = min_t(u64, em->len - offset, length);
> > +
> > +   stripe_len = map->stripe_len;
> > +   /*
> > +    * stripe_nr counts the total number of stripes we have to stride
> > +    * to get to this block
> > +    */
> > +   stripe_nr = div64_u64(offset, stripe_len);
> > +   stripe_offset = stripe_nr * stripe_len;
> > +   ASSERT(offset >= stripe_offset);
> 
> What about a DIV_ROUND_DOWN helper?
> Surprisingly we only have DIR_ROUND_UP, not not DIV_ROUND_DOWN.
> 
> And if we're only going to support 64K stripe len, then round_down() is good
> for current usage.
> 
> > +
> > +   /* stripe_offset is the offset of this block in its stripe */
> > +   stripe_offset = offset - stripe_offset;
> 
> This is a little confusing.
> What about using another variable called @stripe_start instead of using the
> same variable @stripe_offset to temporarily store stripe start bytenr.
> 
> I prefer to do it in one run without resuing @stripe_offset variable to
> avoid confusion.

Right, I was trying to keep the check of (offset >= stripe_offset), but it's not
necessary.

> 
> > +
> > +   stripe_nr_end = ALIGN(offset + length, map->stripe_len);
> 
> round_up() causes less confusion.
> 
> And IIRC, ALIGN/round_up can only handle power of 2, this implies the
> stripe_len must be power of 2, which is OK for now.
> If using ALIGN here, we can also use round_down() in previous stripe_nr.
>

Good point.

Thanks,

-liubo
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to