gfs2: Clean up on-stack transactions
Replace the TR_ALLOCED flag by its inverse, TR_ONSTACK: that way, the flag only needs to be set in the exceptional case of on-stack transactions. Split off __gfs2_trans_begin from gfs2_trans_begin and use it to replace the open-coded version in gfs2_ail_empty_gl. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
Родитель
15e20a301a
Коммит
c968f5788b
|
@ -86,16 +86,12 @@ static int gfs2_ail_empty_gl(struct gfs2_glock *gl)
|
|||
{
|
||||
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
|
||||
struct gfs2_trans tr;
|
||||
unsigned int revokes;
|
||||
int ret;
|
||||
|
||||
memset(&tr, 0, sizeof(tr));
|
||||
INIT_LIST_HEAD(&tr.tr_buf);
|
||||
INIT_LIST_HEAD(&tr.tr_databuf);
|
||||
INIT_LIST_HEAD(&tr.tr_ail1_list);
|
||||
INIT_LIST_HEAD(&tr.tr_ail2_list);
|
||||
tr.tr_revokes = atomic_read(&gl->gl_ail_count);
|
||||
revokes = atomic_read(&gl->gl_ail_count);
|
||||
|
||||
if (!tr.tr_revokes) {
|
||||
if (!revokes) {
|
||||
bool have_revokes;
|
||||
bool log_in_flight;
|
||||
|
||||
|
@ -122,23 +118,14 @@ static int gfs2_ail_empty_gl(struct gfs2_glock *gl)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* A shortened, inline version of gfs2_trans_begin()
|
||||
* tr->alloced is not set since the transaction structure is
|
||||
* on the stack */
|
||||
tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes);
|
||||
tr.tr_ip = _RET_IP_;
|
||||
sb_start_intwrite(sdp->sd_vfs);
|
||||
ret = gfs2_log_reserve(sdp, tr.tr_reserved);
|
||||
if (ret < 0) {
|
||||
sb_end_intwrite(sdp->sd_vfs);
|
||||
return ret;
|
||||
}
|
||||
WARN_ON_ONCE(current->journal_info);
|
||||
current->journal_info = &tr;
|
||||
|
||||
__gfs2_ail_flush(gl, 0, tr.tr_revokes);
|
||||
|
||||
memset(&tr, 0, sizeof(tr));
|
||||
set_bit(TR_ONSTACK, &tr.tr_flags);
|
||||
ret = __gfs2_trans_begin(&tr, sdp, 0, revokes, _RET_IP_);
|
||||
if (ret)
|
||||
goto flush;
|
||||
__gfs2_ail_flush(gl, 0, revokes);
|
||||
gfs2_trans_end(sdp);
|
||||
|
||||
flush:
|
||||
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
|
||||
GFS2_LFC_AIL_EMPTY_GL);
|
||||
|
|
|
@ -490,7 +490,7 @@ struct gfs2_quota_data {
|
|||
enum {
|
||||
TR_TOUCHED = 1,
|
||||
TR_ATTACHED = 2,
|
||||
TR_ALLOCED = 3,
|
||||
TR_ONSTACK = 3,
|
||||
};
|
||||
|
||||
struct gfs2_trans {
|
||||
|
|
|
@ -1114,7 +1114,7 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
|
|||
if (sdp->sd_log_tr) {
|
||||
gfs2_merge_trans(sdp, tr);
|
||||
} else if (tr->tr_num_buf_new || tr->tr_num_databuf_new) {
|
||||
gfs2_assert_withdraw(sdp, test_bit(TR_ALLOCED, &tr->tr_flags));
|
||||
gfs2_assert_withdraw(sdp, !test_bit(TR_ONSTACK, &tr->tr_flags));
|
||||
sdp->sd_log_tr = tr;
|
||||
set_bit(TR_ATTACHED, &tr->tr_flags);
|
||||
}
|
||||
|
|
|
@ -37,10 +37,10 @@ static void gfs2_print_trans(struct gfs2_sbd *sdp, const struct gfs2_trans *tr)
|
|||
tr->tr_num_revoke, tr->tr_num_revoke_rm);
|
||||
}
|
||||
|
||||
int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
|
||||
unsigned int revokes)
|
||||
int __gfs2_trans_begin(struct gfs2_trans *tr, struct gfs2_sbd *sdp,
|
||||
unsigned int blocks, unsigned int revokes,
|
||||
unsigned long ip)
|
||||
{
|
||||
struct gfs2_trans *tr;
|
||||
int error;
|
||||
|
||||
if (current->journal_info) {
|
||||
|
@ -52,15 +52,10 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
|
|||
if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))
|
||||
return -EROFS;
|
||||
|
||||
tr = kmem_cache_zalloc(gfs2_trans_cachep, GFP_NOFS);
|
||||
if (!tr)
|
||||
return -ENOMEM;
|
||||
|
||||
tr->tr_ip = _RET_IP_;
|
||||
tr->tr_ip = ip;
|
||||
tr->tr_blocks = blocks;
|
||||
tr->tr_revokes = revokes;
|
||||
tr->tr_reserved = 1;
|
||||
set_bit(TR_ALLOCED, &tr->tr_flags);
|
||||
if (blocks)
|
||||
tr->tr_reserved += 6 + blocks;
|
||||
if (revokes)
|
||||
|
@ -74,17 +69,28 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
|
|||
sb_start_intwrite(sdp->sd_vfs);
|
||||
|
||||
error = gfs2_log_reserve(sdp, tr->tr_reserved);
|
||||
if (error)
|
||||
goto fail;
|
||||
if (error) {
|
||||
sb_end_intwrite(sdp->sd_vfs);
|
||||
return error;
|
||||
}
|
||||
|
||||
current->journal_info = tr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fail:
|
||||
sb_end_intwrite(sdp->sd_vfs);
|
||||
kmem_cache_free(gfs2_trans_cachep, tr);
|
||||
int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
|
||||
unsigned int revokes)
|
||||
{
|
||||
struct gfs2_trans *tr;
|
||||
int error;
|
||||
|
||||
tr = kmem_cache_zalloc(gfs2_trans_cachep, GFP_NOFS);
|
||||
if (!tr)
|
||||
return -ENOMEM;
|
||||
error = __gfs2_trans_begin(tr, sdp, blocks, revokes, _RET_IP_);
|
||||
if (error)
|
||||
kmem_cache_free(gfs2_trans_cachep, tr);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -92,13 +98,12 @@ void gfs2_trans_end(struct gfs2_sbd *sdp)
|
|||
{
|
||||
struct gfs2_trans *tr = current->journal_info;
|
||||
s64 nbuf;
|
||||
int alloced = test_bit(TR_ALLOCED, &tr->tr_flags);
|
||||
|
||||
current->journal_info = NULL;
|
||||
|
||||
if (!test_bit(TR_TOUCHED, &tr->tr_flags)) {
|
||||
gfs2_log_release(sdp, tr->tr_reserved);
|
||||
if (alloced)
|
||||
if (!test_bit(TR_ONSTACK, &tr->tr_flags))
|
||||
gfs2_trans_free(sdp, tr);
|
||||
sb_end_intwrite(sdp->sd_vfs);
|
||||
return;
|
||||
|
@ -113,7 +118,8 @@ void gfs2_trans_end(struct gfs2_sbd *sdp)
|
|||
gfs2_print_trans(sdp, tr);
|
||||
|
||||
gfs2_log_commit(sdp, tr);
|
||||
if (alloced && !test_bit(TR_ATTACHED, &tr->tr_flags))
|
||||
if (!test_bit(TR_ONSTACK, &tr->tr_flags) &&
|
||||
!test_bit(TR_ATTACHED, &tr->tr_flags))
|
||||
gfs2_trans_free(sdp, tr);
|
||||
up_read(&sdp->sd_log_flush_lock);
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@ static inline unsigned int gfs2_rg_blocks(const struct gfs2_inode *ip, unsigned
|
|||
return rgd->rd_length;
|
||||
}
|
||||
|
||||
extern int __gfs2_trans_begin(struct gfs2_trans *tr, struct gfs2_sbd *sdp,
|
||||
unsigned int blocks, unsigned int revokes,
|
||||
unsigned long ip);
|
||||
extern int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
|
||||
unsigned int revokes);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче