Skip to content

Commit 9136cad

Browse files
author
Andreas Gruenbacher
committed
gfs2: Prevent inode creation race (2)
In gfs2_try_evict(), we try grabbing the inode to evict, we try to evict it, and then we try grabbing it again to see if it still exists. There is no guarantee that we will end up with the same inode both times; the inode validity check that commit ffd1cf0 ("gfs2: Prevent inode creation race") added to the first grab is actually needed both times. (To avoid code duplication, add a grab_existing_inode() helper.) Signed-off-by: Andreas Gruenbacher <[email protected]>
1 parent 6cb3b1c commit 9136cad

File tree

1 file changed

+21
-19
lines changed

1 file changed

+21
-19
lines changed

fs/gfs2/glock.c

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,25 @@ static void gfs2_glock_poke(struct gfs2_glock *gl)
971971
gfs2_holder_uninit(&gh);
972972
}
973973

974+
static struct gfs2_inode *gfs2_grab_existing_inode(struct gfs2_glock *gl)
975+
{
976+
struct gfs2_inode *ip;
977+
978+
spin_lock(&gl->gl_lockref.lock);
979+
ip = gl->gl_object;
980+
if (ip && !igrab(&ip->i_inode))
981+
ip = NULL;
982+
spin_unlock(&gl->gl_lockref.lock);
983+
if (ip) {
984+
wait_on_inode(&ip->i_inode);
985+
if (is_bad_inode(&ip->i_inode)) {
986+
iput(&ip->i_inode);
987+
ip = NULL;
988+
}
989+
}
990+
return ip;
991+
}
992+
974993
static void gfs2_try_evict(struct gfs2_glock *gl)
975994
{
976995
struct gfs2_inode *ip;
@@ -988,32 +1007,15 @@ static void gfs2_try_evict(struct gfs2_glock *gl)
9881007
* happened below. (Verification is triggered by the call to
9891008
* gfs2_queue_verify_delete() in gfs2_evict_inode().)
9901009
*/
991-
spin_lock(&gl->gl_lockref.lock);
992-
ip = gl->gl_object;
993-
if (ip && !igrab(&ip->i_inode))
994-
ip = NULL;
995-
spin_unlock(&gl->gl_lockref.lock);
996-
if (ip) {
997-
wait_on_inode(&ip->i_inode);
998-
if (is_bad_inode(&ip->i_inode)) {
999-
iput(&ip->i_inode);
1000-
ip = NULL;
1001-
}
1002-
}
1010+
ip = gfs2_grab_existing_inode(gl);
10031011
if (ip) {
10041012
set_bit(GLF_DEFER_DELETE, &gl->gl_flags);
10051013
d_prune_aliases(&ip->i_inode);
10061014
iput(&ip->i_inode);
10071015
clear_bit(GLF_DEFER_DELETE, &gl->gl_flags);
10081016

10091017
/* If the inode was evicted, gl->gl_object will now be NULL. */
1010-
spin_lock(&gl->gl_lockref.lock);
1011-
ip = gl->gl_object;
1012-
if (ip) {
1013-
if (!igrab(&ip->i_inode))
1014-
ip = NULL;
1015-
}
1016-
spin_unlock(&gl->gl_lockref.lock);
1018+
ip = gfs2_grab_existing_inode(gl);
10171019
if (ip) {
10181020
gfs2_glock_poke(ip->i_gl);
10191021
iput(&ip->i_inode);

0 commit comments

Comments
 (0)