RISC-V: Canaan devicetree fixes
[linux-2.6-microblaze.git] / fs / gfs2 / glock.c
index 347c7bc..41b6c89 100644 (file)
@@ -405,10 +405,13 @@ static void do_error(struct gfs2_glock *gl, const int ret)
 /**
  * demote_incompat_holders - demote incompatible demoteable holders
  * @gl: the glock we want to promote
- * @new_gh: the new holder to be promoted
+ * @current_gh: the newly promoted holder
+ *
+ * We're passing the newly promoted holder in @current_gh, but actually, any of
+ * the strong holders would do.
  */
 static void demote_incompat_holders(struct gfs2_glock *gl,
-                                   struct gfs2_holder *new_gh)
+                                   struct gfs2_holder *current_gh)
 {
        struct gfs2_holder *gh, *tmp;
 
@@ -424,8 +427,10 @@ static void demote_incompat_holders(struct gfs2_glock *gl,
                 */
                if (!test_bit(HIF_HOLDER, &gh->gh_iflags))
                        return;
+               if (gh == current_gh)
+                       continue;
                if (test_bit(HIF_MAY_DEMOTE, &gh->gh_iflags) &&
-                   !may_grant(gl, new_gh, gh)) {
+                   !may_grant(gl, current_gh, gh)) {
                        /*
                         * We should not recurse into do_promote because
                         * __gfs2_glock_dq only calls handle_callback,
@@ -488,7 +493,7 @@ int gfs2_instantiate(struct gfs2_holder *gh)
 
 again:
        if (!test_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags))
-               return 0;
+               goto done;
 
        /*
         * Since we unlock the lockref lock, we set a flag to indicate
@@ -507,11 +512,17 @@ again:
                goto again;
        }
 
-       ret = glops->go_instantiate(gh);
+       ret = glops->go_instantiate(gl);
        if (!ret)
                clear_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags);
        clear_and_wake_up_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
-       return ret;
+       if (ret)
+               return ret;
+
+done:
+       if (glops->go_held)
+               return glops->go_held(gh);
+       return 0;
 }
 
 /**
@@ -523,32 +534,33 @@ again:
 
 static int do_promote(struct gfs2_glock *gl)
 {
-       struct gfs2_holder *gh, *tmp, *first_gh;
+       struct gfs2_holder *gh, *current_gh;
        bool incompat_holders_demoted = false;
 
-       first_gh = find_first_strong_holder(gl);
-       list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
+       current_gh = find_first_strong_holder(gl);
+       list_for_each_entry(gh, &gl->gl_holders, gh_list) {
                if (test_bit(HIF_HOLDER, &gh->gh_iflags))
                        continue;
-               if (!may_grant(gl, first_gh, gh)) {
+               if (!may_grant(gl, current_gh, gh)) {
                        /*
-                        * If we get here, it means we may not grant this holder for
-                        * some reason. If this holder is the head of the list, it
-                        * means we have a blocked holder at the head, so return 1.
+                        * If we get here, it means we may not grant this
+                        * holder for some reason. If this holder is at the
+                        * head of the list, it means we have a blocked holder
+                        * at the head, so return 1.
                         */
                        if (list_is_first(&gh->gh_list, &gl->gl_holders))
                                return 1;
                        do_error(gl, 0);
                        break;
                }
-               if (!incompat_holders_demoted) {
-                       demote_incompat_holders(gl, first_gh);
-                       incompat_holders_demoted = true;
-                       first_gh = gh;
-               }
                set_bit(HIF_HOLDER, &gh->gh_iflags);
                trace_gfs2_promote(gh);
                gfs2_holder_wake(gh);
+               if (!incompat_holders_demoted) {
+                       current_gh = gh;
+                       demote_incompat_holders(gl, current_gh);
+                       incompat_holders_demoted = true;
+               }
        }
        return 0;
 }
@@ -1450,10 +1462,10 @@ __acquires(&gl->gl_lockref.lock)
 
        if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) {
                if (test_bit(GLF_LOCK, &gl->gl_flags)) {
-                       struct gfs2_holder *first_gh;
+                       struct gfs2_holder *current_gh;
 
-                       first_gh = find_first_strong_holder(gl);
-                       try_futile = !may_grant(gl, first_gh, gh);
+                       current_gh = find_first_strong_holder(gl);
+                       try_futile = !may_grant(gl, current_gh, gh);
                }
                if (test_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags))
                        goto fail;
@@ -1739,7 +1751,7 @@ static int glock_compare(const void *arg_a, const void *arg_b)
 }
 
 /**
- * nq_m_sync - synchonously acquire more than one glock in deadlock free order
+ * nq_m_sync - synchronously acquire more than one glock in deadlock free order
  * @num_gh: the number of structures
  * @ghs: an array of struct gfs2_holder structures
  * @p: placeholder for the holder structure to pass back
@@ -1760,8 +1772,6 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs,
        sort(p, num_gh, sizeof(struct gfs2_holder *), glock_compare, NULL);
 
        for (x = 0; x < num_gh; x++) {
-               p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
-
                error = gfs2_glock_nq(p[x]);
                if (error) {
                        while (x--)
@@ -1778,7 +1788,6 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs,
  * @num_gh: the number of structures
  * @ghs: an array of struct gfs2_holder structures
  *
- *
  * Returns: 0 on success (all glocks acquired),
  *          errno on failure (no glocks acquired)
  */
@@ -1793,7 +1802,6 @@ int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs)
        case 0:
                return 0;
        case 1:
-               ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
                return gfs2_glock_nq(ghs);
        default:
                if (num_gh <= 4)
@@ -2479,7 +2487,7 @@ int __init gfs2_glock_init(void)
                return -ENOMEM;
        }
 
-       ret = register_shrinker(&glock_shrinker);
+       ret = register_shrinker(&glock_shrinker, "gfs2-glock");
        if (ret) {
                destroy_workqueue(gfs2_delete_workqueue);
                destroy_workqueue(glock_workqueue);