diff options
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r-- | fs/gfs2/glock.c | 35 |
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) | |||
764 | static void drop_bh(struct gfs2_glock *gl, unsigned int ret) | 764 | static 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)); |