aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/glock.c35
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/locking/dlm/lock.c3
-rw-r--r--fs/gfs2/locking/dlm/thread.c10
-rw-r--r--fs/gfs2/ops_fstype.c2
5 files changed, 34 insertions, 17 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));
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 4ba2ea63119d..9c2c0b90b22a 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -167,6 +167,7 @@ enum {
167 GLF_DEMOTE_IN_PROGRESS = 6, 167 GLF_DEMOTE_IN_PROGRESS = 6,
168 GLF_LFLUSH = 7, 168 GLF_LFLUSH = 7,
169 GLF_WAITERS2 = 8, 169 GLF_WAITERS2 = 8,
170 GLF_CONV_DEADLK = 9,
170}; 171};
171 172
172struct gfs2_glock { 173struct gfs2_glock {
diff --git a/fs/gfs2/locking/dlm/lock.c b/fs/gfs2/locking/dlm/lock.c
index 542a797ac89a..53a6ab3c0919 100644
--- a/fs/gfs2/locking/dlm/lock.c
+++ b/fs/gfs2/locking/dlm/lock.c
@@ -137,7 +137,8 @@ static inline unsigned int make_flags(struct gdlm_lock *lp,
137 137
138 /* Conversion deadlock avoidance by DLM */ 138 /* Conversion deadlock avoidance by DLM */
139 139
140 if (!test_bit(LFL_FORCE_PROMOTE, &lp->flags) && 140 if (!(lp->ls->fsflags & LM_MFLAG_CONV_NODROP) &&
141 !test_bit(LFL_FORCE_PROMOTE, &lp->flags) &&
141 !(lkf & DLM_LKF_NOQUEUE) && 142 !(lkf & DLM_LKF_NOQUEUE) &&
142 cur > DLM_LOCK_NL && req > DLM_LOCK_NL && cur != req) 143 cur > DLM_LOCK_NL && req > DLM_LOCK_NL && cur != req)
143 lkf |= DLM_LKF_CONVDEADLK; 144 lkf |= DLM_LKF_CONVDEADLK;
diff --git a/fs/gfs2/locking/dlm/thread.c b/fs/gfs2/locking/dlm/thread.c
index 521694fc19d6..e53db6fd28ab 100644
--- a/fs/gfs2/locking/dlm/thread.c
+++ b/fs/gfs2/locking/dlm/thread.c
@@ -135,7 +135,15 @@ static void process_complete(struct gdlm_lock *lp)
135 lp->lksb.sb_status, lp->lockname.ln_type, 135 lp->lksb.sb_status, lp->lockname.ln_type,
136 (unsigned long long)lp->lockname.ln_number, 136 (unsigned long long)lp->lockname.ln_number,
137 lp->flags); 137 lp->flags);
138 return; 138 if (lp->lksb.sb_status == -EDEADLOCK &&
139 lp->ls->fsflags & LM_MFLAG_CONV_NODROP) {
140 lp->req = lp->cur;
141 acb.lc_ret |= LM_OUT_CONV_DEADLK;
142 if (lp->cur == DLM_LOCK_IV)
143 lp->lksb.sb_lkid = 0;
144 goto out;
145 } else
146 return;
139 } 147 }
140 148
141 /* 149 /*
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 5b518f73497a..ef9c6c4f80f6 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -723,7 +723,7 @@ static int gfs2_lm_mount(struct gfs2_sbd *sdp, int silent)
723{ 723{
724 char *proto = sdp->sd_proto_name; 724 char *proto = sdp->sd_proto_name;
725 char *table = sdp->sd_table_name; 725 char *table = sdp->sd_table_name;
726 int flags = 0; 726 int flags = LM_MFLAG_CONV_NODROP;
727 int error; 727 int error;
728 728
729 if (sdp->sd_args.ar_spectator) 729 if (sdp->sd_args.ar_spectator)