NFS: Support non-IPv4 addresses in nfs_parsed_mount_data
[safe/jmp/linux-2.6] / fs / gfs2 / glock.c
index a37efe4..80e09c5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
@@ -217,7 +217,6 @@ int gfs2_glock_put(struct gfs2_glock *gl)
        if (atomic_dec_and_test(&gl->gl_ref)) {
                hlist_del(&gl->gl_list);
                write_unlock(gl_lock_addr(gl->gl_hash));
-               BUG_ON(spin_is_locked(&gl->gl_spin));
                gfs2_assert(sdp, gl->gl_state == LM_ST_UNLOCKED);
                gfs2_assert(sdp, list_empty(&gl->gl_reclaim));
                gfs2_assert(sdp, list_empty(&gl->gl_holders));
@@ -346,7 +345,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
        gl->gl_object = NULL;
        gl->gl_sbd = sdp;
        gl->gl_aspace = NULL;
-       lops_init_le(&gl->gl_le, &gfs2_glock_lops);
        INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
 
        /* If this glock protects actual on-disk data or metadata blocks,
@@ -461,7 +459,6 @@ static void wait_on_holder(struct gfs2_holder *gh)
 
 static void gfs2_demote_wake(struct gfs2_glock *gl)
 {
-       BUG_ON(!spin_is_locked(&gl->gl_spin));
        gl->gl_demote_state = LM_ST_EXCLUSIVE;
         clear_bit(GLF_DEMOTE, &gl->gl_flags);
         smp_mb__after_clear_bit();
@@ -507,21 +504,12 @@ static int rq_mutex(struct gfs2_holder *gh)
 static int rq_promote(struct gfs2_holder *gh)
 {
        struct gfs2_glock *gl = gh->gh_gl;
-       struct gfs2_sbd *sdp = gl->gl_sbd;
 
        if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) {
                if (list_empty(&gl->gl_holders)) {
                        gl->gl_req_gh = gh;
                        set_bit(GLF_LOCK, &gl->gl_flags);
                        spin_unlock(&gl->gl_spin);
-
-                       if (atomic_read(&sdp->sd_reclaim_count) >
-                           gfs2_tune_get(sdp, gt_reclaim_limit) &&
-                           !(gh->gh_flags & LM_FLAG_PRIORITY)) {
-                               gfs2_reclaim_glock(sdp);
-                               gfs2_reclaim_glock(sdp);
-                       }
-
                        gfs2_glock_xmote_th(gh->gh_gl, gh);
                        spin_lock(&gl->gl_spin);
                }
@@ -567,7 +555,10 @@ static int rq_demote(struct gfs2_glock *gl)
                gfs2_demote_wake(gl);
                return 0;
        }
+
        set_bit(GLF_LOCK, &gl->gl_flags);
+       set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
+
        if (gl->gl_demote_state == LM_ST_UNLOCKED ||
            gl->gl_state != LM_ST_EXCLUSIVE) {
                spin_unlock(&gl->gl_spin);
@@ -576,7 +567,9 @@ static int rq_demote(struct gfs2_glock *gl)
                spin_unlock(&gl->gl_spin);
                gfs2_glock_xmote_th(gl, NULL);
        }
+
        spin_lock(&gl->gl_spin);
+       clear_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
 
        return 0;
 }
@@ -598,23 +591,18 @@ static void run_queue(struct gfs2_glock *gl)
                if (!list_empty(&gl->gl_waiters1)) {
                        gh = list_entry(gl->gl_waiters1.next,
                                        struct gfs2_holder, gh_list);
-
-                       if (test_bit(HIF_MUTEX, &gh->gh_iflags))
-                               blocked = rq_mutex(gh);
-                       else
-                               gfs2_assert_warn(gl->gl_sbd, 0);
-
+                       blocked = rq_mutex(gh);
                } else if (test_bit(GLF_DEMOTE, &gl->gl_flags)) {
                        blocked = rq_demote(gl);
+                       if (gl->gl_waiters2 && !blocked) {
+                               set_bit(GLF_DEMOTE, &gl->gl_flags);
+                               gl->gl_demote_state = LM_ST_UNLOCKED;
+                       }
+                       gl->gl_waiters2 = 0;
                } else if (!list_empty(&gl->gl_waiters3)) {
                        gh = list_entry(gl->gl_waiters3.next,
                                        struct gfs2_holder, gh_list);
-
-                       if (test_bit(HIF_PROMOTE, &gh->gh_iflags))
-                               blocked = rq_promote(gh);
-                       else
-                               gfs2_assert_warn(gl->gl_sbd, 0);
-
+                       blocked = rq_promote(gh);
                } else
                        break;
 
@@ -632,27 +620,21 @@ static void run_queue(struct gfs2_glock *gl)
 
 static void gfs2_glmutex_lock(struct gfs2_glock *gl)
 {
-       struct gfs2_holder gh;
-
-       gfs2_holder_init(gl, 0, 0, &gh);
-       set_bit(HIF_MUTEX, &gh.gh_iflags);
-       if (test_and_set_bit(HIF_WAIT, &gh.gh_iflags))
-               BUG();
-
        spin_lock(&gl->gl_spin);
        if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) {
+               struct gfs2_holder gh;
+
+               gfs2_holder_init(gl, 0, 0, &gh);
+               set_bit(HIF_WAIT, &gh.gh_iflags);
                list_add_tail(&gh.gh_list, &gl->gl_waiters1);
+               spin_unlock(&gl->gl_spin);
+               wait_on_holder(&gh);
+               gfs2_holder_uninit(&gh);
        } else {
                gl->gl_owner_pid = current->pid;
                gl->gl_ip = (unsigned long)__builtin_return_address(0);
-               clear_bit(HIF_WAIT, &gh.gh_iflags);
-               smp_mb();
-               wake_up_bit(&gh.gh_iflags, HIF_WAIT);
+               spin_unlock(&gl->gl_spin);
        }
-       spin_unlock(&gl->gl_spin);
-
-       wait_on_holder(&gh);
-       gfs2_holder_uninit(&gh);
 }
 
 /**
@@ -691,7 +673,6 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl)
        gl->gl_owner_pid = 0;
        gl->gl_ip = 0;
        run_queue(gl);
-       BUG_ON(!spin_is_locked(&gl->gl_spin));
        spin_unlock(&gl->gl_spin);
 }
 
@@ -722,7 +703,10 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state,
                }
        } else if (gl->gl_demote_state != LM_ST_UNLOCKED &&
                        gl->gl_demote_state != state) {
-               gl->gl_demote_state = LM_ST_UNLOCKED;
+               if (test_bit(GLF_DEMOTE_IN_PROGRESS,  &gl->gl_flags)) 
+                       gl->gl_waiters2 = 1;
+               else 
+                       gl->gl_demote_state = LM_ST_UNLOCKED;
        }
        spin_unlock(&gl->gl_spin);
 }
@@ -943,8 +927,8 @@ static void gfs2_glock_drop_th(struct gfs2_glock *gl)
        const struct gfs2_glock_operations *glops = gl->gl_ops;
        unsigned int ret;
 
-       if (glops->go_drop_th)
-               glops->go_drop_th(gl);
+       if (glops->go_xmote_th)
+               glops->go_xmote_th(gl);
 
        gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
        gfs2_assert_warn(sdp, list_empty(&gl->gl_holders));
@@ -1156,8 +1140,6 @@ restart:
                return -EIO;
        }
 
-       set_bit(HIF_PROMOTE, &gh->gh_iflags);
-
        spin_lock(&gl->gl_spin);
        add_to_queue(gh);
        run_queue(gl);
@@ -1248,12 +1230,11 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
        list_del_init(&gh->gh_list);
 
        if (list_empty(&gl->gl_holders)) {
-               spin_unlock(&gl->gl_spin);
-
-               if (glops->go_unlock)
+               if (glops->go_unlock) {
+                       spin_unlock(&gl->gl_spin);
                        glops->go_unlock(gh);
-
-               spin_lock(&gl->gl_spin);
+                       spin_lock(&gl->gl_spin);
+               }
                gl->gl_stamp = jiffies;
        }
 
@@ -1910,8 +1891,6 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl)
        print_dbg(gi, "  req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no");
        print_dbg(gi, "  lvb_count = %d\n", atomic_read(&gl->gl_lvb_count));
        print_dbg(gi, "  object = %s\n", (gl->gl_object) ? "yes" : "no");
-       print_dbg(gi, "  le = %s\n",
-                  (list_empty(&gl->gl_le.le_list)) ? "no" : "yes");
        print_dbg(gi, "  reclaim = %s\n",
                   (list_empty(&gl->gl_reclaim)) ? "no" : "yes");
        if (gl->gl_aspace)