diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-08-18 15:51:09 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-08-18 15:51:09 -0400 |
commit | 15d00c0b91ca776b51b5ab04f79ab35b06670d30 (patch) | |
tree | a970b4f59086ecbf7d20ec9b2201cf26b8446019 | |
parent | fcc8abc8d4fcdbddc383091449f3696b411aa8fb (diff) |
[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>
-rw-r--r-- | fs/gfs2/lops.c | 6 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 1 | ||||
-rw-r--r-- | fs/gfs2/ops_address.c | 8 | ||||
-rw-r--r-- | fs/gfs2/ops_super.c | 2 |
4 files changed, 6 insertions, 11 deletions
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index af03bf380f46..04bceb75ff23 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -464,7 +464,7 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) | |||
464 | struct gfs2_inode *ip = GFS2_I(mapping->host); | 464 | struct gfs2_inode *ip = GFS2_I(mapping->host); |
465 | 465 | ||
466 | tr->tr_touched = 1; | 466 | tr->tr_touched = 1; |
467 | if (!list_empty(&bd->bd_list_tr) && | 467 | if (list_empty(&bd->bd_list_tr) && |
468 | (ip->i_di.di_flags & GFS2_DIF_JDATA)) { | 468 | (ip->i_di.di_flags & GFS2_DIF_JDATA)) { |
469 | tr->tr_num_buf++; | 469 | tr->tr_num_buf++; |
470 | list_add(&bd->bd_list_tr, &tr->tr_list_buf); | 470 | 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) | |||
473 | } | 473 | } |
474 | gfs2_trans_add_gl(bd->bd_gl); | 474 | gfs2_trans_add_gl(bd->bd_gl); |
475 | gfs2_log_lock(sdp); | 475 | gfs2_log_lock(sdp); |
476 | if (!list_empty(&le->le_list)) { | 476 | if (list_empty(&le->le_list)) { |
477 | if (ip->i_di.di_flags & GFS2_DIF_JDATA) | 477 | if (ip->i_di.di_flags & GFS2_DIF_JDATA) |
478 | sdp->sd_log_num_jdata++; | 478 | sdp->sd_log_num_jdata++; |
479 | sdp->sd_log_num_databuf++; | 479 | sdp->sd_log_num_databuf++; |
@@ -640,10 +640,10 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
640 | bd_le.le_list); | 640 | bd_le.le_list); |
641 | list_del(&bd1->bd_le.le_list); | 641 | list_del(&bd1->bd_le.le_list); |
642 | sdp->sd_log_num_databuf--; | 642 | sdp->sd_log_num_databuf--; |
643 | |||
644 | bh = bd1->bd_bh; | 643 | bh = bd1->bd_bh; |
645 | if (bh) { | 644 | if (bh) { |
646 | bh->b_private = NULL; | 645 | bh->b_private = NULL; |
646 | get_bh(bh); | ||
647 | gfs2_log_unlock(sdp); | 647 | gfs2_log_unlock(sdp); |
648 | wait_on_buffer(bh); | 648 | wait_on_buffer(bh); |
649 | brelse(bh); | 649 | brelse(bh); |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 42dfd32059bc..502864b24196 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -464,7 +464,6 @@ void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh, | |||
464 | lops_init_le(&bd->bd_le, &gfs2_buf_lops); | 464 | lops_init_le(&bd->bd_le, &gfs2_buf_lops); |
465 | } else { | 465 | } else { |
466 | lops_init_le(&bd->bd_le, &gfs2_databuf_lops); | 466 | lops_init_le(&bd->bd_le, &gfs2_databuf_lops); |
467 | get_bh(bh); | ||
468 | } | 467 | } |
469 | bh->b_private = bd; | 468 | bh->b_private = bd; |
470 | 469 | ||
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 45afd0508689..4c59cb110995 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -581,10 +581,8 @@ static void discard_buffer(struct gfs2_sbd *sdp, struct buffer_head *bh) | |||
581 | if (bd) { | 581 | if (bd) { |
582 | bd->bd_bh = NULL; | 582 | bd->bd_bh = NULL; |
583 | bh->b_private = NULL; | 583 | bh->b_private = NULL; |
584 | gfs2_log_unlock(sdp); | 584 | } |
585 | brelse(bh); | 585 | gfs2_log_unlock(sdp); |
586 | } else | ||
587 | gfs2_log_unlock(sdp); | ||
588 | 586 | ||
589 | lock_buffer(bh); | 587 | lock_buffer(bh); |
590 | clear_buffer_dirty(bh); | 588 | clear_buffer_dirty(bh); |
@@ -598,7 +596,7 @@ static void discard_buffer(struct gfs2_sbd *sdp, struct buffer_head *bh) | |||
598 | 596 | ||
599 | static void gfs2_invalidatepage(struct page *page, unsigned long offset) | 597 | static void gfs2_invalidatepage(struct page *page, unsigned long offset) |
600 | { | 598 | { |
601 | struct gfs2_sbd *sdp = page->mapping->host->i_sb->s_fs_info; | 599 | struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); |
602 | struct buffer_head *head, *bh, *next; | 600 | struct buffer_head *head, *bh, *next; |
603 | unsigned int curr_off = 0; | 601 | unsigned int curr_off = 0; |
604 | 602 | ||
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index 730c7228f6ad..2e392c994ab1 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
@@ -216,8 +216,6 @@ static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
216 | if (error) | 216 | if (error) |
217 | return error; | 217 | return error; |
218 | 218 | ||
219 | memset(buf, 0, sizeof(struct kstatfs)); | ||
220 | |||
221 | buf->f_type = GFS2_MAGIC; | 219 | buf->f_type = GFS2_MAGIC; |
222 | buf->f_bsize = sdp->sd_sb.sb_bsize; | 220 | buf->f_bsize = sdp->sd_sb.sb_bsize; |
223 | buf->f_blocks = sc.sc_total; | 221 | buf->f_blocks = sc.sc_total; |