diff options
Diffstat (limited to 'fs/gfs2/lops.c')
| -rw-r--r-- | fs/gfs2/lops.c | 39 | 
1 files changed, 27 insertions, 12 deletions
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 51d27f00ebb..05bbb124699 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -40,7 +40,7 @@ static void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh)  {  	struct gfs2_bufdata *bd; -	gfs2_assert_withdraw(sdp, test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)); +	BUG_ON(!current->journal_info);  	clear_buffer_dirty(bh);  	if (test_set_buffer_pinned(bh)) @@ -65,6 +65,7 @@ static void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh)   * @sdp: the filesystem the buffer belongs to   * @bh: The buffer to unpin   * @ai: + * @flags: The inode dirty flags   *   */ @@ -73,10 +74,8 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,  {  	struct gfs2_bufdata *bd = bh->b_private; -	gfs2_assert_withdraw(sdp, buffer_uptodate(bh)); - -	if (!buffer_pinned(bh)) -		gfs2_assert_withdraw(sdp, 0); +	BUG_ON(!buffer_uptodate(bh)); +	BUG_ON(!buffer_pinned(bh));  	lock_buffer(bh);  	mark_buffer_dirty(bh); @@ -95,8 +94,7 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,  	list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list);  	spin_unlock(&sdp->sd_ail_lock); -	if (test_and_clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags)) -		gfs2_glock_schedule_for_reclaim(bd->bd_gl); +	clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);  	trace_gfs2_pin(bd, 0);  	unlock_buffer(bh);  	atomic_dec(&sdp->sd_log_pinned); @@ -322,12 +320,16 @@ static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)  static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)  { +	struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le); +	struct gfs2_glock *gl = bd->bd_gl;  	struct gfs2_trans *tr;  	tr = current->journal_info;  	tr->tr_touched = 1;  	tr->tr_num_revoke++;  	sdp->sd_log_num_revoke++; +	atomic_inc(&gl->gl_revokes); +	set_bit(GLF_LFLUSH, &gl->gl_flags);  	list_add(&le->le_list, &sdp->sd_log_le_revoke);  } @@ -350,9 +352,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)  	ld->ld_data1 = cpu_to_be32(sdp->sd_log_num_revoke);  	offset = sizeof(struct gfs2_log_descriptor); -	while (!list_empty(head)) { -		bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list); -		list_del_init(&bd->bd_le.le_list); +	list_for_each_entry(bd, head, bd_le.le_list) {  		sdp->sd_log_num_revoke--;  		if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) { @@ -367,8 +367,6 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)  		}  		*(__be64 *)(bh->b_data + offset) = cpu_to_be64(bd->bd_blkno); -		kmem_cache_free(gfs2_bufdata_cachep, bd); -  		offset += sizeof(u64);  	}  	gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); @@ -376,6 +374,22 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)  	submit_bh(WRITE_SYNC, bh);  } +static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) +{ +	struct list_head *head = &sdp->sd_log_le_revoke; +	struct gfs2_bufdata *bd; +	struct gfs2_glock *gl; + +	while (!list_empty(head)) { +		bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list); +		list_del_init(&bd->bd_le.le_list); +		gl = bd->bd_gl; +		atomic_dec(&gl->gl_revokes); +		clear_bit(GLF_LFLUSH, &gl->gl_flags); +		kmem_cache_free(gfs2_bufdata_cachep, bd); +	} +} +  static void revoke_lo_before_scan(struct gfs2_jdesc *jd,  				  struct gfs2_log_header_host *head, int pass)  { @@ -749,6 +763,7 @@ const struct gfs2_log_operations gfs2_buf_lops = {  const struct gfs2_log_operations gfs2_revoke_lops = {  	.lo_add = revoke_lo_add,  	.lo_before_commit = revoke_lo_before_commit, +	.lo_after_commit = revoke_lo_after_commit,  	.lo_before_scan = revoke_lo_before_scan,  	.lo_scan_elements = revoke_lo_scan_elements,  	.lo_after_scan = revoke_lo_after_scan,  |