All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andreas Gruenbacher <agruenba@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH] gfs2: hole_size improvement
Date: Wed, 11 Apr 2018 15:37:25 +0200	[thread overview]
Message-ID: <CAHc6FU5OfDgS6Q_DBa_Kaa8cjPCuZEXWe=+oFDB0VM03nK0F6Q@mail.gmail.com> (raw)
In-Reply-To: <c1b6d9f4-3882-7e5d-2645-60912a095066@redhat.com>

Hi Andy,

On 11 April 2018 at 15:00, Andrew Price <anprice@redhat.com> wrote:
> Hi Andreas,
>
> I only have a few nitpicks...
>
> On 10/04/18 18:39, Andreas Gruenbacher wrote:
>>
>> Rewrite function hole_size so that it computes the entire size of a
>> hole.  Previously, the hole size returned wasn't guaranteed to span the
>> entire hole and multiple invocations of hole_size could be needed to
>> reach the next bit of data.
>>
>> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
>> ---
>>   fs/gfs2/bmap.c | 106
>> ++++++++++++++++++++++++++++++++++++---------------------
>>   1 file changed, 67 insertions(+), 39 deletions(-)
>>
>> diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
>> index 8c25a64d8ae0..14c21825b890 100644
>> --- a/fs/gfs2/bmap.c
>> +++ b/fs/gfs2/bmap.c
>> @@ -279,6 +279,12 @@ static inline __be64 *metapointer(unsigned int
>> height, const struct metapath *mp
>>         return p + mp->mp_list[height];
>>   }
>>   +static inline const __be64 *metaend(unsigned int height, const struct
>> metapath *mp)
>> +{
>> +       const struct buffer_head *bh = mp->mp_bh[height];
>> +       return (const __be64 *)(bh->b_data + bh->b_size);
>> +}
>> +
>>   static void gfs2_metapath_ra(struct gfs2_glock *gl, __be64 *start,
>> __be64 *end)
>>   {
>>         const __be64 *t;
>> @@ -631,56 +637,78 @@ static int gfs2_iomap_alloc(struct inode *inode,
>> struct iomap *iomap,
>>    * hole_size - figure out the size of a hole
>>    * @inode: The inode
>>    * @lblock: The logical starting block number
>> - * @mp: The metapath
>> + * @mp: The metapath at lblock
>> + * @pholesz: The hole size in bytes (output)
>> + *
>> + * This function modifies @mp.
>>    *
>> - * Returns: The hole size in bytes
>> + * Returns: errno on error
>>    *
>>    */
>> -static u64 hole_size(struct inode *inode, sector_t lblock, struct
>> metapath *mp)
>> +static int hole_size(struct inode *inode, sector_t lblock, struct
>> metapath *mp,
>> +                    u64 *pholesz)
>>   {
>> +       sector_t lblock_end = (i_size_read(inode) + i_blocksize(inode) -
>> 1) >>
>> +                             inode->i_blkbits;
>>         struct gfs2_inode *ip = GFS2_I(inode);
>>         struct gfs2_sbd *sdp = GFS2_SB(inode);
>> -       struct metapath mp_eof;
>> -       u64 factor = 1;
>> -       int hgt;
>> -       u64 holesz = 0;
>>         const __be64 *first, *end, *ptr;
>> -       const struct buffer_head *bh;
>> -       u64 lblock_stop = (i_size_read(inode) - 1) >> inode->i_blkbits;
>> -       int zeroptrs;
>> -       bool done = false;
>> -
>> -       /* Get another metapath, to the very last byte */
>> -       find_metapath(sdp, lblock_stop, &mp_eof, ip->i_height);
>> -       for (hgt = ip->i_height - 1; hgt >= 0 && !done; hgt--) {
>> -               bh = mp->mp_bh[hgt];
>> -               if (bh) {
>> -                       zeroptrs = 0;
>> -                       first = metapointer(hgt, mp);
>> -                       end = (const __be64 *)(bh->b_data + bh->b_size);
>> -
>> -                       for (ptr = first; ptr < end; ptr++) {
>> -                               if (*ptr) {
>> -                                       done = true;
>> -                                       break;
>> -                               } else {
>> -                                       zeroptrs++;
>> -                               }
>> +       u64 holesz = 0, factor = 1;
>> +       int hgt, ret;
>
> hgt could be unsigned for consistency and checking.

Right, it can't go negative (anymore).

>> +
>> +       for (hgt = ip->i_height - 1; hgt >= mp->mp_aheight; hgt--)
>> +               factor *= sdp->sd_inptrs;
>> +
>> +       for (;;) {
>> +               /* Count the number of zero pointers.  */
>> +               first = metapointer(hgt, mp);
>> +               end = metaend(hgt, mp);
>> +               if (end - first > lblock_end - lblock - holesz)
>> +                       end = first + lblock_end - lblock - holesz;
>> +               for (ptr = first; ptr < end; ptr++) {
>> +                       if (*ptr) {
>> +                               holesz += (ptr - first) * factor;
>> +                               if (hgt == ip->i_height - 1)
>> +                                       goto out;
>> +                               mp->mp_list[hgt] += (ptr - first);
>> +                               goto fill_up_metapath;
>>                         }
>> -               } else {
>> -                       zeroptrs = sdp->sd_inptrs;
>>                 }
>> -               if (factor * zeroptrs >= lblock_stop - lblock + 1) {
>> -                       holesz = lblock_stop - lblock + 1;
>> -                       break;
>> +               holesz += (ptr - first) * factor;
>> +
>> +lower_metapath:
>> +               /* Decrease height of metapath. */
>> +               brelse(mp->mp_bh[hgt]);
>> +               mp->mp_bh[hgt] = NULL;
>> +               mp->mp_list[hgt] = 0;
>> +               if (!hgt)
>> +                       goto out;
>> +               hgt--;
>> +               factor *= sdp->sd_inptrs;
>> +
>> +               /* Advance in metadata tree. */
>> +               (mp->mp_list[hgt])++;
>> +               first = metapointer(hgt, mp);
>> +               end = metaend(hgt, mp);
>> +               if (first >= end) {
>> +                       if (!hgt)
>> +                               goto out;
>> +                       goto lower_metapath;
>>                 }
>> -               holesz += factor * zeroptrs;
>>   -             factor *= sdp->sd_inptrs;
>> -               if (hgt && (mp->mp_list[hgt - 1] < mp_eof.mp_list[hgt -
>> 1]))
>> -                       (mp->mp_list[hgt - 1])++;
>> +fill_up_metapath:
>> +               /* Fill up metapath. */
>
> Comment could be removed as the function name and the label are the same as
> the comment :)

Ok.

>> +               ret = fillup_metapath(ip, mp, ip->i_height - 1);
>> +               if (ret < 0)
>> +                       return ret;
>> +               while (ret--) {
>> +                       hgt++;
>
>
> Could be taken out of the loop as hgt += ret
>
> The flow is a little hard to follow but I don't see any obvious problems.
> Has it been tested with directories as well as files?

No, I need to think the directory case through some more. The only
"hole" in directories is at the end of the file though.

> Reviewed-by: Andrew Price <anprice@redhat.com>
>
> Andy
>
>> +                       factor /= sdp->sd_inptrs;
>> +               }
>>         }
>> -       return holesz << inode->i_blkbits;
>> +out:
>> +       *pholesz = holesz << inode->i_blkbits;
>> +       return 0;
>>   }
>>     static void gfs2_stuffed_iomap(struct inode *inode, struct iomap
>> *iomap)
>> @@ -804,7 +832,7 @@ int gfs2_iomap_begin(struct inode *inode, loff_t pos,
>> loff_t length,
>>                 if (pos >= size)
>>                         ret = -ENOENT;
>>                 else if (height <= ip->i_height)
>> -                       iomap->length = hole_size(inode, lblock, &mp);
>> +                       ret = hole_size(inode, lblock, &mp,
>> &iomap->length);
>>                 else
>>                         iomap->length = size - pos;
>>         }

Thanks,
Andreas



      reply	other threads:[~2018-04-11 13:37 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-10 17:39 [Cluster-devel] [PATCH] gfs2: hole_size improvement Andreas Gruenbacher
2018-04-10 18:22 ` Andreas Gruenbacher
2018-04-10 19:28   ` Andreas Gruenbacher
2018-04-11 13:00 ` Andrew Price
2018-04-11 13:37   ` Andreas Gruenbacher [this message]

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='CAHc6FU5OfDgS6Q_DBa_Kaa8cjPCuZEXWe=+oFDB0VM03nK0F6Q@mail.gmail.com' \
    --to=agruenba@redhat.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 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.