diff options
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r-- | fs/gfs2/log.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 58e237fba565..00a2e721a374 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -31,11 +31,12 @@ #include "dir.h" #include "trace_gfs2.h" +static void gfs2_log_shutdown(struct gfs2_sbd *sdp); + /** * gfs2_struct2blk - compute stuff * @sdp: the filesystem * @nstruct: the number of structures - * @ssize: the size of the structures * * Compute the number of log descriptor blocks needed to hold a certain number * of structures of a certain size. @@ -43,18 +44,16 @@ * Returns: the number of blocks needed (minimum is always 1) */ -unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, - unsigned int ssize) +unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct) { unsigned int blks; unsigned int first, second; blks = 1; - first = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / ssize; + first = sdp->sd_ldptrs; if (nstruct > first) { - second = (sdp->sd_sb.sb_bsize - - sizeof(struct gfs2_meta_header)) / ssize; + second = sdp->sd_inptrs; blks += DIV_ROUND_UP(nstruct - first, second); } @@ -159,7 +158,8 @@ restart: list_for_each_entry_reverse(tr, head, tr_list) { if (wbc->nr_to_write <= 0) break; - if (gfs2_ail1_start_one(sdp, wbc, tr, &withdraw)) + if (gfs2_ail1_start_one(sdp, wbc, tr, &withdraw) && + !gfs2_withdrawn(sdp)) goto restart; } spin_unlock(&sdp->sd_ail_lock); @@ -469,9 +469,8 @@ static unsigned int calc_reserved(struct gfs2_sbd *sdp) reserved += DIV_ROUND_UP(dbuf, databuf_limit(sdp)); } - if (sdp->sd_log_commited_revoke > 0) - reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, - sizeof(u64)); + if (sdp->sd_log_committed_revoke > 0) + reserved += gfs2_struct2blk(sdp, sdp->sd_log_committed_revoke); /* One for the overall header */ if (reserved) reserved++; @@ -609,6 +608,14 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) list_add(&bd->bd_list, &sdp->sd_log_revokes); } +void gfs2_glock_remove_revoke(struct gfs2_glock *gl) +{ + if (atomic_dec_return(&gl->gl_revokes) == 0) { + clear_bit(GLF_LFLUSH, &gl->gl_flags); + gfs2_glock_queue_put(gl); + } +} + void gfs2_write_revokes(struct gfs2_sbd *sdp) { struct gfs2_trans *tr; @@ -682,12 +689,16 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, { struct gfs2_log_header *lh; u32 hash, crc; - struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); + struct page *page; struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; struct timespec64 tv; struct super_block *sb = sdp->sd_vfs; u64 dblock; + if (gfs2_withdrawn(sdp)) + goto out; + + page = mempool_alloc(gfs2_page_pool, GFP_NOIO); lh = page_address(page); clear_page(lh); @@ -707,7 +718,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, lh->lh_nsec = cpu_to_be32(tv.tv_nsec); lh->lh_sec = cpu_to_be64(tv.tv_sec); if (!list_empty(&jd->extent_list)) - dblock = gfs2_log_bmap(sdp); + dblock = gfs2_log_bmap(jd, lblock); else { int ret = gfs2_lblk_to_dblk(jd->jd_inode, lblock, &dblock); if (gfs2_assert_withdraw(sdp, ret == 0)) @@ -740,6 +751,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock); gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE | op_flags); +out: log_flush_wait(sdp); } @@ -768,6 +780,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); gfs2_write_log_header(sdp, sdp->sd_jdesc, sdp->sd_log_sequence++, tail, sdp->sd_log_flush_head, flags, op_flags); + gfs2_log_incr_head(sdp); if (sdp->sd_log_tail != tail) log_pull_tail(sdp, tail); @@ -812,7 +825,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags) if (unlikely(state == SFS_FROZEN)) gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); gfs2_assert_withdraw(sdp, - sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); + sdp->sd_log_num_revoke == sdp->sd_log_committed_revoke); gfs2_ordered_write(sdp); lops_before_commit(sdp, tr); @@ -831,7 +844,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags) gfs2_log_lock(sdp); sdp->sd_log_head = sdp->sd_log_flush_head; sdp->sd_log_blks_reserved = 0; - sdp->sd_log_commited_revoke = 0; + sdp->sd_log_committed_revoke = 0; spin_lock(&sdp->sd_ail_lock); if (tr && !list_empty(&tr->tr_ail1_list)) { @@ -882,6 +895,7 @@ static void gfs2_merge_trans(struct gfs2_trans *old, struct gfs2_trans *new) old->tr_num_buf_rm += new->tr_num_buf_rm; old->tr_num_databuf_rm += new->tr_num_databuf_rm; old->tr_num_revoke += new->tr_num_revoke; + old->tr_num_revoke_rm += new->tr_num_revoke_rm; list_splice_tail_init(&new->tr_databuf, &old->tr_databuf); list_splice_tail_init(&new->tr_buf, &old->tr_buf); @@ -903,7 +917,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_committed_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; reserved = calc_reserved(sdp); maxres = sdp->sd_log_blks_reserved + tr->tr_reserved; gfs2_assert_withdraw(sdp, maxres >= reserved); @@ -948,7 +962,7 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) * */ -void gfs2_log_shutdown(struct gfs2_sbd *sdp) +static void gfs2_log_shutdown(struct gfs2_sbd *sdp) { gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); |