aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2008-03-14 14:52:52 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2008-03-31 05:41:44 -0400
commit58e9fee13e579df44922172dbe3c9e3ba3edf7a3 (patch)
tree7b134f28032a3cd498b2d9a18c02ea085c0725e2 /fs/gfs2/glock.c
parentf5a8cd020173c455705fc0095b7d299da6f8f87b (diff)
[GFS2] Invalidate cache at correct point
GFS2 wasn't invalidating its cache before it called into the lock manager with a request that could potentially drop a lock. This was leaving a window where the lock could be actually be held by another node, but the file's page cache would still appear valid, causing coherency problems. This patch moves the cache invalidation to before the lock manager call when dropping a lock. It also adds the option to the lock_dlm lock manager to not use conversion mode deadlock avoidance, which, on a conversion from shared to exclusive, could internally drop the lock, and then reacquire in. GFS2 now asks lock_dlm to not do this. Instead, GFS2 manually drops the lock and reacquires it. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 63981e2fb835..d636b3e80f5d 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -764,7 +764,7 @@ static void state_change(struct gfs2_glock *gl, unsigned int new_state)
764static void drop_bh(struct gfs2_glock *gl, unsigned int ret) 764static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
765{ 765{
766 struct gfs2_sbd *sdp = gl->gl_sbd; 766 struct gfs2_sbd *sdp = gl->gl_sbd;
767 const struct gfs2_glock_operations *glops = gl->gl_ops; 767 struct gfs2_holder *gh = gl->gl_req_gh;
768 768
769 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); 769 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
770 gfs2_assert_warn(sdp, list_empty(&gl->gl_holders)); 770 gfs2_assert_warn(sdp, list_empty(&gl->gl_holders));
@@ -772,8 +772,14 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
772 772
773 state_change(gl, LM_ST_UNLOCKED); 773 state_change(gl, LM_ST_UNLOCKED);
774 774
775 if (glops->go_inval) 775 if (test_and_clear_bit(GLF_CONV_DEADLK, &gl->gl_flags)) {
776 glops->go_inval(gl, DIO_METADATA); 776 spin_lock(&gl->gl_spin);
777 gh->gh_error = 0;
778 spin_unlock(&gl->gl_spin);
779 gfs2_glock_xmote_th(gl, gl->gl_req_gh);
780 gfs2_glock_put(gl);
781 return;
782 }
777 783
778 spin_lock(&gl->gl_spin); 784 spin_lock(&gl->gl_spin);
779 gfs2_demote_wake(gl); 785 gfs2_demote_wake(gl);
@@ -794,7 +800,6 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
794 struct gfs2_sbd *sdp = gl->gl_sbd; 800 struct gfs2_sbd *sdp = gl->gl_sbd;
795 const struct gfs2_glock_operations *glops = gl->gl_ops; 801 const struct gfs2_glock_operations *glops = gl->gl_ops;
796 struct gfs2_holder *gh = gl->gl_req_gh; 802 struct gfs2_holder *gh = gl->gl_req_gh;
797 int prev_state = gl->gl_state;
798 int op_done = 1; 803 int op_done = 1;
799 804
800 if (!gh && (ret & LM_OUT_ST_MASK) == LM_ST_UNLOCKED) { 805 if (!gh && (ret & LM_OUT_ST_MASK) == LM_ST_UNLOCKED) {
@@ -808,16 +813,6 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
808 813
809 state_change(gl, ret & LM_OUT_ST_MASK); 814 state_change(gl, ret & LM_OUT_ST_MASK);
810 815
811 if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) {
812 if (glops->go_inval)
813 glops->go_inval(gl, DIO_METADATA);
814 } else if (gl->gl_state == LM_ST_DEFERRED) {
815 /* We might not want to do this here.
816 Look at moving to the inode glops. */
817 if (glops->go_inval)
818 glops->go_inval(gl, 0);
819 }
820
821 /* Deal with each possible exit condition */ 816 /* Deal with each possible exit condition */
822 817
823 if (!gh) { 818 if (!gh) {
@@ -837,6 +832,14 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
837 } 832 }
838 } else { 833 } else {
839 spin_lock(&gl->gl_spin); 834 spin_lock(&gl->gl_spin);
835 if (ret & LM_OUT_CONV_DEADLK) {
836 gh->gh_error = 0;
837 set_bit(GLF_CONV_DEADLK, &gl->gl_flags);
838 spin_unlock(&gl->gl_spin);
839 gfs2_glock_drop_th(gl);
840 gfs2_glock_put(gl);
841 return;
842 }
840 list_del_init(&gh->gh_list); 843 list_del_init(&gh->gh_list);
841 gh->gh_error = -EIO; 844 gh->gh_error = -EIO;
842 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) 845 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
@@ -910,6 +913,8 @@ static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh)
910 913
911 if (glops->go_xmote_th) 914 if (glops->go_xmote_th)
912 glops->go_xmote_th(gl); 915 glops->go_xmote_th(gl);
916 if (state == LM_ST_DEFERRED && glops->go_inval)
917 glops->go_inval(gl, DIO_METADATA);
913 918
914 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); 919 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
915 gfs2_assert_warn(sdp, list_empty(&gl->gl_holders)); 920 gfs2_assert_warn(sdp, list_empty(&gl->gl_holders));
@@ -952,6 +957,8 @@ static void gfs2_glock_drop_th(struct gfs2_glock *gl)
952 957
953 if (glops->go_xmote_th) 958 if (glops->go_xmote_th)
954 glops->go_xmote_th(gl); 959 glops->go_xmote_th(gl);
960 if (glops->go_inval)
961 glops->go_inval(gl, DIO_METADATA);
955 962
956 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); 963 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
957 gfs2_assert_warn(sdp, list_empty(&gl->gl_holders)); 964 gfs2_assert_warn(sdp, list_empty(&gl->gl_holders));