diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2017-06-30 08:16:46 -0500 |
---|---|---|
committer | Bob Peterson <rpeterso@redhat.com> | 2017-07-05 07:21:07 -0500 |
commit | e0b62e21b71bbe6d1015fe3e891cd9f50d04e660 (patch) | |
tree | c96f76569f65d182f60486d7f8ac5bfb5d23a3f3 /fs/gfs2/super.c | |
parent | 6b0c7440bcb4b7e5a64836132caf56bf19a33f6e (diff) | |
download | linux-rpi3-e0b62e21b71bbe6d1015fe3e891cd9f50d04e660.tar.gz linux-rpi3-e0b62e21b71bbe6d1015fe3e891cd9f50d04e660.tar.bz2 linux-rpi3-e0b62e21b71bbe6d1015fe3e891cd9f50d04e660.zip |
gfs2: gfs2_create_inode: Keep glock across iput
On failure, keep the inode glock across the final iput of the new inode
so that gfs2_evict_inode doesn't have to re-acquire the glock. That
way, gfs2_evict_inode won't need to revalidate the block type.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r-- | fs/gfs2/super.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index bd5ad6c5514e..fdedec379b78 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1538,6 +1538,12 @@ static void gfs2_evict_inode(struct inode *inode) if (inode->i_nlink || (sb->s_flags & MS_RDONLY)) goto out; + if (test_bit(GIF_ALLOC_FAILED, &ip->i_flags)) { + BUG_ON(!gfs2_glock_is_locked_by_me(ip->i_gl)); + gfs2_holder_mark_uninitialized(&gh); + goto alloc_failed; + } + /* Must not read inode block until block type has been verified */ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh); if (unlikely(error)) { @@ -1546,11 +1552,9 @@ static void gfs2_evict_inode(struct inode *inode) goto out; } - if (!test_bit(GIF_ALLOC_FAILED, &ip->i_flags)) { - error = gfs2_check_blk_type(sdp, ip->i_no_addr, GFS2_BLKST_UNLINKED); - if (error) - goto out_truncate; - } + error = gfs2_check_blk_type(sdp, ip->i_no_addr, GFS2_BLKST_UNLINKED); + if (error) + goto out_truncate; if (test_bit(GIF_INVALID, &ip->i_flags)) { error = gfs2_inode_refresh(ip); @@ -1558,6 +1562,7 @@ static void gfs2_evict_inode(struct inode *inode) goto out_truncate; } +alloc_failed: if (gfs2_holder_initialized(&ip->i_iopen_gh) && test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { ip->i_iopen_gh.gh_flags |= GL_NOCACHE; @@ -1624,7 +1629,8 @@ out_unlock: } gfs2_holder_uninit(&ip->i_iopen_gh); } - gfs2_glock_dq_uninit(&gh); + if (gfs2_holder_initialized(&gh)) + gfs2_glock_dq_uninit(&gh); if (error && error != GLR_TRYFAILED && error != -EROFS) fs_warn(sdp, "gfs2_evict_inode: %d\n", error); out: |