Skip to content

Commit

Permalink
GFS2: Fix race between lru_list and glock ref count
Browse files Browse the repository at this point in the history
This patch fixes a narrow race window between the glock ref count
hitting zero and glocks being removed from the lru_list.

Signed-off-by: Steven Whitehouse <[email protected]>
  • Loading branch information
swhiteho committed Feb 28, 2012
1 parent 586c6e7 commit 4043b88
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions fs/gfs2/glock.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,19 @@ void gfs2_glock_add_to_lru(struct gfs2_glock *gl)
spin_unlock(&lru_lock);
}

static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
static void __gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
{
spin_lock(&lru_lock);
if (!list_empty(&gl->gl_lru)) {
list_del_init(&gl->gl_lru);
atomic_dec(&lru_count);
clear_bit(GLF_LRU, &gl->gl_flags);
}
}

static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
{
spin_lock(&lru_lock);
__gfs2_glock_remove_from_lru(gl);
spin_unlock(&lru_lock);
}

Expand Down Expand Up @@ -217,11 +222,12 @@ void gfs2_glock_put(struct gfs2_glock *gl)
struct gfs2_sbd *sdp = gl->gl_sbd;
struct address_space *mapping = gfs2_glock2aspace(gl);

if (atomic_dec_and_test(&gl->gl_ref)) {
if (atomic_dec_and_lock(&gl->gl_ref, &lru_lock)) {
__gfs2_glock_remove_from_lru(gl);
spin_unlock(&lru_lock);
spin_lock_bucket(gl->gl_hash);
hlist_bl_del_rcu(&gl->gl_list);
spin_unlock_bucket(gl->gl_hash);
gfs2_glock_remove_from_lru(gl);
GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
GLOCK_BUG_ON(gl, mapping && mapping->nrpages);
trace_gfs2_glock_put(gl);
Expand Down

0 comments on commit 4043b88

Please sign in to comment.