From: Steven Whitehouse <swhiteho@redhat.com> Date: Tue, 7 Oct 2008 16:47:14 +0100 Subject: [gfs2] fix jdata page invalidation Message-id: 1223394434.25004.8.camel@quoit O-Subject: [RHEL 5.3] GFS2: Patch to fix jdata page invalidation (bz #437803) Bugzilla: 437803 RH-Acked-by: Abhijith Das <adas@redhat.com> This is a RHEL5 version of an upstream patch (posted for review but not in the -nmw tree yet, due to pending merge window, but will be in the tree once thats sorted out). It fixes a problem relating to journaled data mode where we tried to take pages out of the journal while not in a transaction. This fixes the problem (bz #437803), Steve. diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index d058d84..8aadb1e 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c @@ -227,25 +227,23 @@ static int gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc { struct inode *inode = page->mapping->host; struct gfs2_sbd *sdp = GFS2_SB(inode); - int error; + int ret; int done_trans = 0; - error = gfs2_writepage_common(page, wbc); - if (error <= 0) - return error; - if (PageChecked(page)) { if (wbc->sync_mode != WB_SYNC_ALL) goto out_ignore; - error = gfs2_do_trans_begin(sdp, RES_DINODE + 1, 0, 0); - if (error) + ret = gfs2_do_trans_begin(sdp, RES_DINODE + 1, 0, 0); + if (ret) goto out_ignore; done_trans = 1; } - error = __gfs2_jdata_writepage(page, wbc); + ret = gfs2_writepage_common(page, wbc); + if (ret > 0) + ret = __gfs2_jdata_writepage(page, wbc); if (done_trans) gfs2_trans_end(sdp); - return error; + return ret; out_ignore: redirty_page_for_writepage(wbc, page); diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index fa323f3..32eff05 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c @@ -495,7 +495,7 @@ static void gfs2_delete_inode(struct inode *inode) gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); error = gfs2_glock_nq(&ip->i_iopen_gh); if (error) - goto out_uninit; + goto out_truncate; if (S_ISDIR(inode->i_mode) && (ip->i_di.di_flags & GFS2_DIF_EXHASH)) { @@ -520,6 +520,7 @@ static void gfs2_delete_inode(struct inode *inode) if (error) goto out_unlock; +out_truncate: error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); if (error) goto out_unlock; @@ -528,8 +529,8 @@ static void gfs2_delete_inode(struct inode *inode) gfs2_trans_end(sdp); out_unlock: - gfs2_glock_dq(&ip->i_iopen_gh); -out_uninit: + if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) + gfs2_glock_dq(&ip->i_iopen_gh); gfs2_holder_uninit(&ip->i_iopen_gh); gfs2_glock_dq_uninit(&gh); if (error && error != GLR_TRYFAILED)