aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
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));