gfs2: Move lock flush locking to gfs2_trans_{begin,end}
Move the read locking of sd_log_flush_lock from gfs2_log_reserve to gfs2_trans_begin, and its unlocking from gfs2_log_release to gfs2_trans_end. Use gfs2_log_release in two places in which it was open coded before. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
parent
f3708fb59f
commit
c1eba1b0bc
|
@ -420,7 +420,6 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
|
|||
trace_gfs2_log_blocks(sdp, blks);
|
||||
gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <=
|
||||
sdp->sd_jdesc->jd_blocks);
|
||||
up_read(&sdp->sd_log_flush_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -439,22 +438,16 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
|
|||
* with queued waiters, we use an exclusive wait. This means that when we
|
||||
* get woken with enough journal space to get our reservation, we need to
|
||||
* wake the next waiter on the list.
|
||||
*
|
||||
* Returns: errno
|
||||
*/
|
||||
|
||||
int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
|
||||
void gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned reserved_blks = 7 * (4096 / sdp->sd_vfs->s_blocksize);
|
||||
unsigned wanted = blks + reserved_blks;
|
||||
DEFINE_WAIT(wait);
|
||||
int did_wait = 0;
|
||||
unsigned int free_blocks;
|
||||
|
||||
if (gfs2_assert_warn(sdp, blks) ||
|
||||
gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks))
|
||||
return -EINVAL;
|
||||
atomic_add(blks, &sdp->sd_log_blks_needed);
|
||||
retry:
|
||||
free_blocks = atomic_read(&sdp->sd_log_blks_free);
|
||||
|
@ -482,13 +475,6 @@ retry:
|
|||
*/
|
||||
if (unlikely(did_wait))
|
||||
wake_up(&sdp->sd_log_waitq);
|
||||
|
||||
down_read(&sdp->sd_log_flush_lock);
|
||||
if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))) {
|
||||
gfs2_log_release(sdp, blks);
|
||||
ret = -EROFS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -585,12 +571,7 @@ static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail)
|
|||
unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail);
|
||||
|
||||
ail2_empty(sdp, new_tail);
|
||||
|
||||
atomic_add(dist, &sdp->sd_log_blks_free);
|
||||
trace_gfs2_log_blocks(sdp, dist);
|
||||
gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <=
|
||||
sdp->sd_jdesc->jd_blocks);
|
||||
|
||||
gfs2_log_release(sdp, dist);
|
||||
sdp->sd_log_tail = new_tail;
|
||||
}
|
||||
|
||||
|
@ -1127,10 +1108,7 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
|
|||
maxres = sdp->sd_log_blks_reserved + tr->tr_reserved;
|
||||
gfs2_assert_withdraw(sdp, maxres >= reserved);
|
||||
unused = maxres - reserved;
|
||||
atomic_add(unused, &sdp->sd_log_blks_free);
|
||||
trace_gfs2_log_blocks(sdp, unused);
|
||||
gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <=
|
||||
sdp->sd_jdesc->jd_blocks);
|
||||
gfs2_log_release(sdp, unused);
|
||||
sdp->sd_log_blks_reserved = reserved;
|
||||
|
||||
gfs2_log_unlock(sdp);
|
||||
|
|
|
@ -66,7 +66,7 @@ extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct);
|
|||
extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
|
||||
extern bool gfs2_log_is_empty(struct gfs2_sbd *sdp);
|
||||
extern void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks);
|
||||
extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks);
|
||||
extern void gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks);
|
||||
extern void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
|
||||
u64 seq, u32 tail, u32 lblock, u32 flags,
|
||||
int op_flags);
|
||||
|
|
|
@ -41,8 +41,6 @@ int __gfs2_trans_begin(struct gfs2_trans *tr, struct gfs2_sbd *sdp,
|
|||
unsigned int blocks, unsigned int revokes,
|
||||
unsigned long ip)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (current->journal_info) {
|
||||
gfs2_print_trans(sdp, current->journal_info);
|
||||
BUG();
|
||||
|
@ -66,14 +64,20 @@ int __gfs2_trans_begin(struct gfs2_trans *tr, struct gfs2_sbd *sdp,
|
|||
INIT_LIST_HEAD(&tr->tr_ail1_list);
|
||||
INIT_LIST_HEAD(&tr->tr_ail2_list);
|
||||
|
||||
if (gfs2_assert_warn(sdp, tr->tr_reserved <= sdp->sd_jdesc->jd_blocks))
|
||||
return -EINVAL;
|
||||
|
||||
sb_start_intwrite(sdp->sd_vfs);
|
||||
|
||||
error = gfs2_log_reserve(sdp, tr->tr_reserved);
|
||||
if (error) {
|
||||
gfs2_log_reserve(sdp, tr->tr_reserved);
|
||||
|
||||
down_read(&sdp->sd_log_flush_lock);
|
||||
if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))) {
|
||||
gfs2_log_release(sdp, tr->tr_reserved);
|
||||
up_read(&sdp->sd_log_flush_lock);
|
||||
sb_end_intwrite(sdp->sd_vfs);
|
||||
if (error == -EROFS)
|
||||
wake_up(&sdp->sd_log_waitq);
|
||||
return error;
|
||||
return -EROFS;
|
||||
}
|
||||
|
||||
current->journal_info = tr;
|
||||
|
@ -105,6 +109,7 @@ void gfs2_trans_end(struct gfs2_sbd *sdp)
|
|||
|
||||
if (!test_bit(TR_TOUCHED, &tr->tr_flags)) {
|
||||
gfs2_log_release(sdp, tr->tr_reserved);
|
||||
up_read(&sdp->sd_log_flush_lock);
|
||||
if (!test_bit(TR_ONSTACK, &tr->tr_flags))
|
||||
gfs2_trans_free(sdp, tr);
|
||||
sb_end_intwrite(sdp->sd_vfs);
|
||||
|
|
Loading…
Reference in New Issue