[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;