Skip to content

Commit 053640a

Browse files
AstralBobAndreas Gruenbacher
authored andcommitted
gfs2: Dequeue waiters when withdrawn
When a withdraw occurs, ordinary (not system) glocks may not be granted anymore. Later, when the file system is unmounted, gfs2_gl_hash_clear() tries to clear out all the glocks, but these un-grantable pending waiters prevent some glocks from being freed. So the unmount hangs, at least for its ten-minute timeout period. This patch takes measures to remove any pending waiters from the glocks that will never be granted. This allows the unmount to proceed in a reasonable period of time. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
1 parent 04133b6 commit 053640a

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

fs/gfs2/glock.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,6 +2196,20 @@ static void dump_glock_func(struct gfs2_glock *gl)
21962196
dump_glock(NULL, gl, true);
21972197
}
21982198

2199+
static void withdraw_dq(struct gfs2_glock *gl)
2200+
{
2201+
spin_lock(&gl->gl_lockref.lock);
2202+
if (!__lockref_is_dead(&gl->gl_lockref) &&
2203+
glock_blocked_by_withdraw(gl))
2204+
do_error(gl, LM_OUT_ERROR); /* remove pending waiters */
2205+
spin_unlock(&gl->gl_lockref.lock);
2206+
}
2207+
2208+
void gfs2_gl_dq_holders(struct gfs2_sbd *sdp)
2209+
{
2210+
glock_hash_walk(withdraw_dq, sdp);
2211+
}
2212+
21992213
/**
22002214
* gfs2_gl_hash_clear - Empty out the glock hash table
22012215
* @sdp: the filesystem

fs/gfs2/glock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ extern void gfs2_cancel_delete_work(struct gfs2_glock *gl);
274274
extern bool gfs2_delete_work_queued(const struct gfs2_glock *gl);
275275
extern void gfs2_flush_delete_work(struct gfs2_sbd *sdp);
276276
extern void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
277+
extern void gfs2_gl_dq_holders(struct gfs2_sbd *sdp);
277278
extern void gfs2_glock_thaw(struct gfs2_sbd *sdp);
278279
extern void gfs2_glock_add_to_lru(struct gfs2_glock *gl);
279280
extern void gfs2_glock_free(struct gfs2_glock *gl);

fs/gfs2/util.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp)
164164
}
165165
if (!ret)
166166
gfs2_make_fs_ro(sdp);
167+
/*
168+
* Dequeue any pending non-system glock holders that can no
169+
* longer be granted because the file system is withdrawn.
170+
*/
171+
gfs2_gl_dq_holders(sdp);
167172
gfs2_freeze_unlock(&freeze_gh);
168173
}
169174

0 commit comments

Comments
 (0)