From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bob Peterson Date: Wed, 13 Nov 2019 15:30:18 -0600 Subject: [Cluster-devel] [PATCH 20/32] gfs2: new slab for transactions In-Reply-To: <20191113213030.237431-1-rpeterso@redhat.com> References: <20191113213030.237431-1-rpeterso@redhat.com> Message-ID: <20191113213030.237431-21-rpeterso@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit This patch adds a new slab for gfs2 transactions. That allows us to have an initialization function and protect against some errors. Signed-off-by: Bob Peterson --- fs/gfs2/glops.c | 1 + fs/gfs2/log.c | 14 +++++++++++--- fs/gfs2/lops.c | 4 ++++ fs/gfs2/main.c | 23 +++++++++++++++++++++++ fs/gfs2/trans.c | 28 ++++++++++++++++++++++------ fs/gfs2/trans.h | 1 + fs/gfs2/util.c | 1 + fs/gfs2/util.h | 1 + 8 files changed, 64 insertions(+), 9 deletions(-) diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index d8f9ee756c0e..e0219b0e2229 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -89,6 +89,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) memset(&tr, 0, sizeof(tr)); INIT_LIST_HEAD(&tr.tr_buf); INIT_LIST_HEAD(&tr.tr_databuf); + set_bit(TR_ATTACHED, &tr.tr_flags); /* prevent gfs2_trans_end free */ tr.tr_revokes = atomic_read(&gl->gl_ail_count); if (!tr.tr_revokes) diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index bb0ef8ede14c..11aa65dae761 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -30,6 +30,7 @@ #include "util.h" #include "dir.h" #include "trace_gfs2.h" +#include "trans.h" /** * gfs2_struct2blk - compute stuff @@ -329,7 +330,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) list_del(&tr->tr_list); gfs2_assert_warn(sdp, list_empty(&tr->tr_ail1_list)); gfs2_assert_warn(sdp, list_empty(&tr->tr_ail2_list)); - kfree(tr); + gfs2_trans_free(sdp, tr); } spin_unlock(&sdp->sd_ail_lock); @@ -866,7 +867,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags) trace_gfs2_log_flush(sdp, 0, flags); up_write(&sdp->sd_log_flush_lock); - kfree(tr); + gfs2_trans_free(sdp, tr); } /** @@ -885,6 +886,12 @@ static void gfs2_merge_trans(struct gfs2_trans *old, struct gfs2_trans *new) old->tr_num_databuf_rm += new->tr_num_databuf_rm; old->tr_num_revoke += new->tr_num_revoke; + new->tr_num_buf_new = 0; + new->tr_num_buf_rm = 0; + new->tr_num_databuf_new = 0; + new->tr_num_databuf_rm = 0; + new->tr_num_revoke = 0; + list_splice_tail_init(&new->tr_databuf, &old->tr_databuf); list_splice_tail_init(&new->tr_buf, &old->tr_buf); } @@ -894,6 +901,7 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) unsigned int reserved; unsigned int unused; unsigned int maxres; + unsigned int new_revokes = tr->tr_num_revoke; gfs2_log_lock(sdp); @@ -905,7 +913,7 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) set_bit(TR_ATTACHED, &tr->tr_flags); } - sdp->sd_log_commited_revoke += tr->tr_num_revoke; + sdp->sd_log_commited_revoke += new_revokes; reserved = calc_reserved(sdp); maxres = sdp->sd_log_blks_reserved + tr->tr_reserved; gfs2_assert_withdraw(sdp, maxres >= reserved); diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 7dda50717c9e..c62b9e12aed7 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -718,6 +718,8 @@ static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) list_del_init(&bd->bd_list); gfs2_unpin(sdp, bd->bd_bh, tr); } + tr->tr_num_buf_new = 0; + tr->tr_num_buf_rm = 0; } static void buf_lo_before_scan(struct gfs2_jdesc *jd, @@ -1070,6 +1072,8 @@ static void databuf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) list_del_init(&bd->bd_list); gfs2_unpin(sdp, bd->bd_bh, tr); } + tr->tr_num_databuf_new = 0; + tr->tr_num_databuf_rm = 0; } diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index a1a295b739fb..5ff114bbcede 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c @@ -68,6 +68,19 @@ static void gfs2_init_gl_aspace_once(void *foo) address_space_init_once(mapping); } +static void gfs2_init_tr_once(void *foo) +{ + struct gfs2_trans *tr = foo; + + memset(tr, 0, sizeof(struct gfs2_trans)); + INIT_LIST_HEAD(&tr->tr_databuf); + INIT_LIST_HEAD(&tr->tr_buf); + INIT_LIST_HEAD(&tr->tr_ail1_list); + INIT_LIST_HEAD(&tr->tr_ail2_list); + INIT_LIST_HEAD(&tr->tr_list); + tr->tr_ip = 0; +} + /** * init_gfs2_fs - Register GFS2 as a filesystem * @@ -143,6 +156,13 @@ static int __init init_gfs2_fs(void) if (!gfs2_qadata_cachep) goto fail_cachep7; + gfs2_trans_cachep = kmem_cache_create("gfs2_trans", + sizeof(struct gfs2_trans), + 0, SLAB_CONSISTENCY_CHECKS| + SLAB_POISON, gfs2_init_tr_once); + if (!gfs2_trans_cachep) + goto fail_cachep8; + error = register_shrinker(&gfs2_qd_shrinker); if (error) goto fail_shrinker; @@ -194,6 +214,8 @@ static int __init init_gfs2_fs(void) fail_fs1: unregister_shrinker(&gfs2_qd_shrinker); fail_shrinker: + kmem_cache_destroy(gfs2_trans_cachep); +fail_cachep8: kmem_cache_destroy(gfs2_qadata_cachep); fail_cachep7: kmem_cache_destroy(gfs2_quotad_cachep); @@ -236,6 +258,7 @@ static void __exit exit_gfs2_fs(void) rcu_barrier(); mempool_destroy(gfs2_page_pool); + kmem_cache_destroy(gfs2_trans_cachep); kmem_cache_destroy(gfs2_qadata_cachep); kmem_cache_destroy(gfs2_quotad_cachep); kmem_cache_destroy(gfs2_rgrpd_cachep); diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index 35e3059255fe..7d16d9aa3153 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c @@ -37,7 +37,7 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) return -EROFS; - tr = kzalloc(sizeof(struct gfs2_trans), GFP_NOFS); + tr = kmem_cache_alloc(gfs2_trans_cachep, GFP_NOFS); if (!tr) return -ENOMEM; @@ -45,14 +45,19 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, tr->tr_blocks = blocks; tr->tr_revokes = revokes; tr->tr_reserved = 1; + tr->tr_num_revoke = 0; + + clear_bit(TR_TOUCHED, &tr->tr_flags); + clear_bit(TR_ATTACHED, &tr->tr_flags); + set_bit(TR_ALLOCED, &tr->tr_flags); if (blocks) tr->tr_reserved += 6 + blocks; if (revokes) tr->tr_reserved += gfs2_struct2blk(sdp, revokes, sizeof(u64)); - INIT_LIST_HEAD(&tr->tr_databuf); - INIT_LIST_HEAD(&tr->tr_buf); + gfs2_assert_warn(sdp, list_empty(&tr->tr_databuf)); + gfs2_assert_warn(sdp, list_empty(&tr->tr_buf)); sb_start_intwrite(sdp->sd_vfs); @@ -66,7 +71,7 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, fail: sb_end_intwrite(sdp->sd_vfs); - kfree(tr); + kmem_cache_free(gfs2_trans_cachep, tr); return error; } @@ -94,7 +99,7 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) if (!test_bit(TR_TOUCHED, &tr->tr_flags)) { gfs2_log_release(sdp, tr->tr_reserved); if (alloced) { - kfree(tr); + gfs2_trans_free(sdp, tr); sb_end_intwrite(sdp->sd_vfs); } return; @@ -110,7 +115,7 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) gfs2_log_commit(sdp, tr); if (alloced && !test_bit(TR_ATTACHED, &tr->tr_flags)) - kfree(tr); + gfs2_trans_free(sdp, tr); up_read(&sdp->sd_log_flush_lock); if (sdp->sd_vfs->s_flags & SB_SYNCHRONOUS) @@ -271,3 +276,14 @@ void gfs2_trans_remove_revoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len) gfs2_log_unlock(sdp); } +void gfs2_trans_free(struct gfs2_sbd *sdp, struct gfs2_trans *tr) +{ + if (tr == NULL) + return; + + gfs2_assert_warn(sdp, list_empty(&tr->tr_ail1_list)); + gfs2_assert_warn(sdp, list_empty(&tr->tr_ail2_list)); + gfs2_assert_warn(sdp, list_empty(&tr->tr_databuf)); + gfs2_assert_warn(sdp, list_empty(&tr->tr_buf)); + kmem_cache_free(gfs2_trans_cachep, tr); +} diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h index 6071334de035..83199ce5a5c5 100644 --- a/fs/gfs2/trans.h +++ b/fs/gfs2/trans.h @@ -42,5 +42,6 @@ extern void gfs2_trans_add_data(struct gfs2_glock *gl, struct buffer_head *bh); extern void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh); extern void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd); extern void gfs2_trans_remove_revoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len); +extern void gfs2_trans_free(struct gfs2_sbd *sdp, struct gfs2_trans *tr); #endif /* __TRANS_DOT_H__ */ diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 690a2f575709..04141d0d8e17 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c @@ -32,6 +32,7 @@ struct kmem_cache *gfs2_bufdata_cachep __read_mostly; struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; struct kmem_cache *gfs2_quotad_cachep __read_mostly; struct kmem_cache *gfs2_qadata_cachep __read_mostly; +struct kmem_cache *gfs2_trans_cachep __read_mostly; mempool_t *gfs2_page_pool __read_mostly; void gfs2_assert_i(struct gfs2_sbd *sdp) diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h index 297eabc29856..72faee19c38d 100644 --- a/fs/gfs2/util.h +++ b/fs/gfs2/util.h @@ -154,6 +154,7 @@ extern struct kmem_cache *gfs2_bufdata_cachep; extern struct kmem_cache *gfs2_rgrpd_cachep; extern struct kmem_cache *gfs2_quotad_cachep; extern struct kmem_cache *gfs2_qadata_cachep; +extern struct kmem_cache *gfs2_trans_cachep; extern mempool_t *gfs2_page_pool; extern struct workqueue_struct *gfs2_control_wq; -- 2.23.0