Commit 15d00c0b authored by Steven Whitehouse's avatar Steven Whitehouse
Browse files

[GFS2] Fix leak of gfs2_bufdata



This fixes a memory leak of struct gfs2_bufdata and also some
problems in the ordered write handling code. It needs a bit
more testing, but I believe that the reference counting of
ordered write buffers should now be correct.

This is aimed at fixing Red Hat bugzilla: #201028 and #201082

Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent fcc8abc8
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -464,7 +464,7 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
	struct gfs2_inode *ip = GFS2_I(mapping->host);

	tr->tr_touched = 1;
	if (!list_empty(&bd->bd_list_tr) &&
	if (list_empty(&bd->bd_list_tr) &&
	    (ip->i_di.di_flags & GFS2_DIF_JDATA)) {
		tr->tr_num_buf++;
		list_add(&bd->bd_list_tr, &tr->tr_list_buf);
@@ -473,7 +473,7 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
	}
	gfs2_trans_add_gl(bd->bd_gl);
	gfs2_log_lock(sdp);
	if (!list_empty(&le->le_list)) {
	if (list_empty(&le->le_list)) {
		if (ip->i_di.di_flags & GFS2_DIF_JDATA)
			sdp->sd_log_num_jdata++;
		sdp->sd_log_num_databuf++;
@@ -640,10 +640,10 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
				 bd_le.le_list);
		list_del(&bd1->bd_le.le_list);
		sdp->sd_log_num_databuf--;

		bh = bd1->bd_bh;
		if (bh) {
			bh->b_private = NULL;
			get_bh(bh);
			gfs2_log_unlock(sdp);
			wait_on_buffer(bh);
			brelse(bh);
+0 −1
Original line number Diff line number Diff line
@@ -464,7 +464,6 @@ void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh,
		lops_init_le(&bd->bd_le, &gfs2_buf_lops);
	} else {
		lops_init_le(&bd->bd_le, &gfs2_databuf_lops);
		get_bh(bh);
	}
	bh->b_private = bd;

+3 −5
Original line number Diff line number Diff line
@@ -581,9 +581,7 @@ static void discard_buffer(struct gfs2_sbd *sdp, struct buffer_head *bh)
	if (bd) {
		bd->bd_bh = NULL;
		bh->b_private = NULL;
		gfs2_log_unlock(sdp);
		brelse(bh);
	} else
	}
	gfs2_log_unlock(sdp);

	lock_buffer(bh);
@@ -598,7 +596,7 @@ static void discard_buffer(struct gfs2_sbd *sdp, struct buffer_head *bh)

static void gfs2_invalidatepage(struct page *page, unsigned long offset)
{
	struct gfs2_sbd *sdp = page->mapping->host->i_sb->s_fs_info;
	struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
	struct buffer_head *head, *bh, *next;
	unsigned int curr_off = 0;

+0 −2
Original line number Diff line number Diff line
@@ -216,8 +216,6 @@ static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
	if (error)
		return error;

	memset(buf, 0, sizeof(struct kstatfs));

	buf->f_type = GFS2_MAGIC;
	buf->f_bsize = sdp->sd_sb.sb_bsize;
	buf->f_blocks = sc.sc_total;