[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: Steven Whitehouse <swhiteho@redhat.com>
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index af03bf3..04bceb7 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c
@@ -464,7 +464,7 @@ 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 @@ } 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 @@ 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);
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 42dfd32..502864b 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c
@@ -464,7 +464,6 @@ 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;
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 45afd05..4c59cb1 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c
@@ -581,10 +581,8 @@ if (bd) { bd->bd_bh = NULL; bh->b_private = NULL; - gfs2_log_unlock(sdp); - brelse(bh); - } else - gfs2_log_unlock(sdp); + } + gfs2_log_unlock(sdp); lock_buffer(bh); clear_buffer_dirty(bh); @@ -598,7 +596,7 @@ 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;
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index 730c722..2e392c9 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c
@@ -216,8 +216,6 @@ 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;