Skip to content

Commit 0abd155

Browse files
Al ViroAndreas Gruenbacher
authored andcommitted
gfs2: fix an oops in gfs2_permission
In RCU mode, we might race with gfs2_evict_inode(), which zeroes ->i_gl. Freeing of the object it points to is RCU-delayed, so if we manage to fetch the pointer before it's been replaced with NULL, we are fine. Check if we'd fetched NULL and treat that as "bail out and tell the caller to get out of RCU mode". Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
1 parent 4c6a081 commit 0abd155

2 files changed

Lines changed: 10 additions & 3 deletions

File tree

fs/gfs2/inode.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,14 +1868,21 @@ int gfs2_permission(struct mnt_idmap *idmap, struct inode *inode,
18681868
{
18691869
struct gfs2_inode *ip;
18701870
struct gfs2_holder i_gh;
1871+
struct gfs2_glock *gl;
18711872
int error;
18721873

18731874
gfs2_holder_mark_uninitialized(&i_gh);
18741875
ip = GFS2_I(inode);
1875-
if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) {
1876+
gl = rcu_dereference(ip->i_gl);
1877+
if (unlikely(!gl)) {
1878+
/* inode is getting torn down, must be RCU mode */
1879+
WARN_ON_ONCE(!(mask & MAY_NOT_BLOCK));
1880+
return -ECHILD;
1881+
}
1882+
if (gfs2_glock_is_locked_by_me(gl) == NULL) {
18761883
if (mask & MAY_NOT_BLOCK)
18771884
return -ECHILD;
1878-
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
1885+
error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
18791886
if (error)
18801887
return error;
18811888
}

fs/gfs2/super.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,7 @@ static void gfs2_evict_inode(struct inode *inode)
15401540
wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE);
15411541
gfs2_glock_add_to_lru(ip->i_gl);
15421542
gfs2_glock_put_eventually(ip->i_gl);
1543-
ip->i_gl = NULL;
1543+
rcu_assign_pointer(ip->i_gl, NULL);
15441544
}
15451545
}
15461546

0 commit comments

Comments
 (0)