Before this patch, function gfs2_evict_inode would check if i_nlink was non-zero, and if so, go to label out. The problem is, the evicted file may still have outstanding pages that need invalidating, but the call to truncate_inode_pages_final at label out doesn't start a transaction. It needs a transaction in order to write revokes for any pages it has to invalidate.
This patch removes the early check for i_nlink in gfs2_evict_inode. Not much further down in the code, there's another check for i_nlink that skips to out_truncate. That one is proper because the calls to truncate_inode_pages after out_truncate use a proper transaction, so the page invalidates and subsequent revokes may be done properly. Signed-off-by: Bob Peterson <rpete...@redhat.com> --- fs/gfs2/super.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 80ac446f0110..1f3dee740431 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1344,7 +1344,7 @@ static void gfs2_evict_inode(struct inode *inode) return; } - if (inode->i_nlink || sb_rdonly(sb)) + if (sb_rdonly(sb)) goto out; if (test_bit(GIF_ALLOC_FAILED, &ip->i_flags)) { @@ -1370,15 +1370,19 @@ static void gfs2_evict_inode(struct inode *inode) } if (gfs2_inode_already_deleted(ip->i_gl, ip->i_no_formal_ino)) - goto out_truncate; + goto out_flush; error = gfs2_check_blk_type(sdp, ip->i_no_addr, GFS2_BLKST_UNLINKED); - if (error) - goto out_truncate; + if (error) { + error = 0; + goto out_flush; + } if (test_bit(GIF_INVALID, &ip->i_flags)) { error = gfs2_inode_refresh(ip); - if (error) - goto out_truncate; + if (error) { + error = 0; + goto out_flush; + } } /* @@ -1392,7 +1396,7 @@ static void gfs2_evict_inode(struct inode *inode) test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { if (!gfs2_upgrade_iopen_glock(inode)) { gfs2_holder_uninit(&ip->i_iopen_gh); - goto out_truncate; + goto out_flush; } } @@ -1424,7 +1428,7 @@ static void gfs2_evict_inode(struct inode *inode) gfs2_inode_remember_delete(ip->i_gl, ip->i_no_formal_ino); goto out_unlock; -out_truncate: +out_flush: gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL | GFS2_LFC_EVICT_INODE); metamapping = gfs2_glock2aspace(ip->i_gl); @@ -1435,6 +1439,7 @@ static void gfs2_evict_inode(struct inode *inode) write_inode_now(inode, 1); gfs2_ail_flush(ip->i_gl, 0); +out_truncate: nr_revokes = inode->i_mapping->nrpages + metamapping->nrpages; if (!nr_revokes) goto out_unlock; -- 2.26.2