[Cluster-devel] [PATCH] gfs2: Allocate bufdata object before taking log lock

Andreas Gruenbacher agruenba at redhat.com
Wed Apr 7 19:43:08 UTC 2021


On Tue, Apr 6, 2021 at 7:09 PM Andreas Gruenbacher <agruenba at redhat.com> wrote:
> Before this patch, functions gfs2_trans_add_{meta,data} would take the
> log lock, then if they needed to allocate a new bufdata object, they
> would drop the lock and reacquire it.  This patch changes it so that if
> there's apparently no bufdata object, it allocates a new one before
> taking the log lock.  After taking the log lock, it checks for conflicts
> and takes measures to resolve the conflict.  This is for performance.
>
> I haven't verified if the page locking in gfs2_trans_add_meta,
> originally introduced in commit 18ec7d5c3f434 ("Make journaled data
> files identical to normal files on disk"), is actually still needed.

This patch is still causing locking issues, so we'll leave it out for now.

> Signed-off-by: Andreas Gruenbacher <agruenba at redhat.com>
> ---
>  fs/gfs2/trans.c | 46 +++++++++++++++++++++++++---------------------
>  1 file changed, 25 insertions(+), 21 deletions(-)
>
> diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
> index 63fec11ef2ce..c50de22d7cbf 100644
> --- a/fs/gfs2/trans.c
> +++ b/fs/gfs2/trans.c
> @@ -171,7 +171,6 @@ static struct gfs2_bufdata *gfs2_alloc_bufdata(struct gfs2_glock *gl,
>         INIT_LIST_HEAD(&bd->bd_list);
>         INIT_LIST_HEAD(&bd->bd_ail_st_list);
>         INIT_LIST_HEAD(&bd->bd_ail_gl_list);
> -       bh->b_private = bd;
>         return bd;
>  }
>
> @@ -193,24 +192,24 @@ void gfs2_trans_add_data(struct gfs2_glock *gl, struct buffer_head *bh)
>  {
>         struct gfs2_trans *tr = current->journal_info;
>         struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
> -       struct gfs2_bufdata *bd;
> +       struct gfs2_bufdata *bd = NULL;
>
>         lock_buffer(bh);
>         if (buffer_pinned(bh)) {
>                 set_bit(TR_TOUCHED, &tr->tr_flags);
>                 goto out;
>         }
> -       gfs2_log_lock(sdp);
> -       bd = bh->b_private;
> -       if (bd == NULL) {
> -               gfs2_log_unlock(sdp);
> +       if (!bh->b_private) {
>                 unlock_buffer(bh);
> -               if (bh->b_private == NULL)
> -                       bd = gfs2_alloc_bufdata(gl, bh);
> -               else
> -                       bd = bh->b_private;
> +               bd = gfs2_alloc_bufdata(gl, bh);
>                 lock_buffer(bh);
> -               gfs2_log_lock(sdp);
> +       }
> +       gfs2_log_lock(sdp);
> +       if (bh->b_private) {
> +               kfree(bd);
> +               bd = bh->b_private;
> +       } else {
> +               bh->b_private = bd;
>         }
>         gfs2_assert(sdp, bd->bd_gl == gl);
>         set_bit(TR_TOUCHED, &tr->tr_flags);
> @@ -230,7 +229,7 @@ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh)
>  {
>
>         struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
> -       struct gfs2_bufdata *bd;
> +       struct gfs2_bufdata *bd = NULL;
>         struct gfs2_meta_header *mh;
>         struct gfs2_trans *tr = current->journal_info;
>         enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state);
> @@ -240,19 +239,24 @@ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh)
>                 set_bit(TR_TOUCHED, &tr->tr_flags);
>                 goto out;
>         }
> -       gfs2_log_lock(sdp);
> -       bd = bh->b_private;
> -       if (bd == NULL) {
> -               gfs2_log_unlock(sdp);
> +       if (!bh->b_private) {
>                 unlock_buffer(bh);
> +               bd = gfs2_alloc_bufdata(gl, bh);
> +               lock_buffer(bh);
> +       }
> +       gfs2_log_lock(sdp);
> +       if (bh->b_private) {
> +               kfree(bd);
> +               bd = bh->b_private;
> +       } else {
>                 lock_page(bh->b_page);
> -               if (bh->b_private == NULL)
> -                       bd = gfs2_alloc_bufdata(gl, bh);
> -               else
> +               if (bh->b_private) {
> +                       kfree(bd);
>                         bd = bh->b_private;
> +               } else {
> +                       bh->b_private = bd;
> +               }
>                 unlock_page(bh->b_page);
> -               lock_buffer(bh);
> -               gfs2_log_lock(sdp);
>         }
>         gfs2_assert(sdp, bd->bd_gl == gl);
>         set_bit(TR_TOUCHED, &tr->tr_flags);
> --
> 2.26.3
>

Thanks,
Andreas




More information about the Cluster-devel mailing list