Commit 49462e2b authored by Bob Peterson's avatar Bob Peterson Committed by Andreas Gruenbacher
Browse files

gfs2: release iopen glock early in evict



Before this patch, evict would clear the iopen glock's gl_object after
releasing the inode glock.  In the meantime, another process could reuse
the same block and thus glocks for a new inode.  It would lock the inode
glock (exclusively), and then the iopen glock (shared).  The shared
locking mode doesn't provide any ordering against the evict, so by the
time the iopen glock is reused, evict may not have gotten to setting
gl_object to NULL.

Fix that by releasing the iopen glock before the inode glock in
gfs2_evict_inode.

Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com&gt;gl_object>
Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
parent 7a92deaa
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -1402,13 +1402,6 @@ static void gfs2_evict_inode(struct inode *inode)
	gfs2_ordered_del_inode(ip);
	clear_inode(inode);
	gfs2_dir_hash_inval(ip);
	if (ip->i_gl) {
		glock_clear_object(ip->i_gl, ip);
		wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE);
		gfs2_glock_add_to_lru(ip->i_gl);
		gfs2_glock_put_eventually(ip->i_gl);
		ip->i_gl = NULL;
	}
	if (gfs2_holder_initialized(&ip->i_iopen_gh)) {
		struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;

@@ -1421,6 +1414,13 @@ static void gfs2_evict_inode(struct inode *inode)
		gfs2_holder_uninit(&ip->i_iopen_gh);
		gfs2_glock_put_eventually(gl);
	}
	if (ip->i_gl) {
		glock_clear_object(ip->i_gl, ip);
		wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE);
		gfs2_glock_add_to_lru(ip->i_gl);
		gfs2_glock_put_eventually(ip->i_gl);
		ip->i_gl = NULL;
	}
}

static struct inode *gfs2_alloc_inode(struct super_block *sb)