aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_inode.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2008-02-22 11:07:18 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2008-03-31 05:41:12 -0400
commit7afd88d9166a752b52517648bcbe923e05d393fc (patch)
tree2fb945189e3cb1be7ad007088f8ec86e9f67ece6 /fs/gfs2/ops_inode.c
parent60b779cfc1fa52034a996ee12a23b62d32e86000 (diff)
[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>
Diffstat (limited to 'fs/gfs2/ops_inode.c')
-rw-r--r--fs/gfs2/ops_inode.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 301c94596678..af7097a514c1 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -898,7 +898,7 @@ static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
898 int error; 898 int error;
899 int unlock = 0; 899 int unlock = 0;
900 900
901 if (gfs2_glock_is_locked_by_me(ip->i_gl) == 0) { 901 if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) {
902 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); 902 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
903 if (error) 903 if (error)
904 return error; 904 return error;
@@ -1065,7 +1065,7 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
1065 int error; 1065 int error;
1066 int unlock = 0; 1066 int unlock = 0;
1067 1067
1068 if (gfs2_glock_is_locked_by_me(ip->i_gl) == 0) { 1068 if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) {
1069 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); 1069 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
1070 if (error) 1070 if (error)
1071 return error; 1071 return error;