[GFS2] Fix a page lock / glock deadlock

We've previously been using a "try lock" in readpage on the basis that
it would prevent deadlocks due to the inverted lock ordering (our normal
lock ordering is glock first and then page lock). Unfortunately tests
have shown that this isn't enough. If the glock has a demote request
queued such that run_queue() in the glock code tries to do a demote when
its called under readpage then it will try and write out all the dirty
pages which requires locking them. This then deadlocks with the page
locked by readpage.

The solution is to always require two calls into readpage. The first
unlocks the page, gets the glock and returns AOP_TRUNCATED_PAGE, the
second does the actual readpage and unlocks the glock & page as
required.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
This commit is contained in:
Steven Whitehouse
2008-02-22 16:07:18 +00:00
부모 60b779cfc1
커밋 7afd88d916
5개의 변경된 파일27개의 추가작업 그리고 25개의 파일을 삭제

파일 보기

@@ -32,24 +32,23 @@
#define GLR_TRYFAILED 13
#define GLR_CANCELED 14
static inline int gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
{
struct gfs2_holder *gh;
int locked = 0;
struct pid *pid;
/* Look in glock's list of holders for one with current task as owner */
spin_lock(&gl->gl_spin);
pid = task_pid(current);
list_for_each_entry(gh, &gl->gl_holders, gh_list) {
if (gh->gh_owner_pid == pid) {
locked = 1;
break;
}
if (gh->gh_owner_pid == pid)
goto out;
}
gh = NULL;
out:
spin_unlock(&gl->gl_spin);
return locked;
return gh;
}
static inline int gfs2_glock_is_held_excl(struct gfs2_glock *gl)