]> err.no Git - linux-2.6/blobdiff - fs/gfs2/glock.c
[netdrvr] wd: fix build breakage with new NS8390p API
[linux-2.6] / fs / gfs2 / glock.c
index be7ed503f012d5042826d28cd5f8a89fc165f1b9..13391e546616ce47a9b413dde1ac73ad396d808d 100644 (file)
@@ -267,8 +267,12 @@ static inline int may_grant(const struct gfs2_glock *gl, const struct gfs2_holde
                return 1;
        if (gh->gh_flags & GL_EXACT)
                return 0;
-       if (gh->gh_state == LM_ST_SHARED && gl->gl_state == LM_ST_EXCLUSIVE)
-               return 1;
+       if (gl->gl_state == LM_ST_EXCLUSIVE) {
+               if (gh->gh_state == LM_ST_SHARED && gh_head->gh_state == LM_ST_SHARED)
+                       return 1;
+               if (gh->gh_state == LM_ST_DEFERRED && gh_head->gh_state == LM_ST_DEFERRED)
+                       return 1;
+       }
        if (gl->gl_state != LM_ST_UNLOCKED && (gh->gh_flags & LM_FLAG_ANY))
                return 1;
        return 0;
@@ -587,6 +591,7 @@ static void run_queue(struct gfs2_glock *gl, const int nonblock)
                if (nonblock)
                        goto out_sched;
                set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
+               GLOCK_BUG_ON(gl, gl->gl_demote_state == LM_ST_EXCLUSIVE);
                gl->gl_target = gl->gl_demote_state;
        } else {
                if (test_bit(GLF_DEMOTE, &gl->gl_flags))
@@ -617,7 +622,9 @@ static void glock_work_func(struct work_struct *work)
        if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags))
                finish_xmote(gl, gl->gl_reply);
        spin_lock(&gl->gl_spin);
-       if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags)) {
+       if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
+           gl->gl_state != LM_ST_UNLOCKED &&
+           gl->gl_demote_state != LM_ST_EXCLUSIVE) {
                unsigned long holdtime, now = jiffies;
                holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time;
                if (time_before(now, holdtime))
@@ -1316,11 +1323,6 @@ void gfs2_glock_cb(void *cb_data, unsigned int type, void *data)
                        wake_up_process(sdp->sd_recoverd_process);
                return;
 
-       case LM_CB_DROPLOCKS:
-               gfs2_gl_hash_clear(sdp, NO_WAIT);
-               gfs2_quota_scan(sdp);
-               return;
-
        default:
                gfs2_assert_warn(sdp, 0);
                return;
@@ -1508,11 +1510,10 @@ static void clear_glock(struct gfs2_glock *gl)
  * @sdp: the filesystem
  * @wait: wait until it's all gone
  *
- * Called when unmounting the filesystem, or when inter-node lock manager
- * requests DROPLOCKS because it is running out of capacity.
+ * Called when unmounting the filesystem.
  */
 
-void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait)
+void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
 {
        unsigned long t;
        unsigned int x;
@@ -1527,7 +1528,7 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait)
                                cont = 1;
                }
 
-               if (!wait || !cont)
+               if (!cont)
                        break;
 
                if (time_after_eq(jiffies,