Merge branch 'for-linus' into for-linus-3.12
[firefly-linux-kernel-4.4.55.git] / fs / gfs2 / glock.c
index 544a809819c3ee5c16ddaa42a8ce0ce26d2194f4..c2f41b4d00b9872ccfb4f5f23f988d46f154df32 100644 (file)
@@ -1411,7 +1411,6 @@ __acquires(&lru_lock)
                if (demote_ok(gl))
                        handle_callback(gl, LM_ST_UNLOCKED, 0, false);
                WARN_ON(!test_and_clear_bit(GLF_LOCK, &gl->gl_flags));
-               smp_mb__after_clear_bit();
                if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
                        gfs2_glock_put_nolock(gl);
                spin_unlock(&gl->gl_spin);
@@ -1428,21 +1427,22 @@ __acquires(&lru_lock)
  * gfs2_dispose_glock_lru() above.
  */
 
-static void gfs2_scan_glock_lru(int nr)
+static long gfs2_scan_glock_lru(int nr)
 {
        struct gfs2_glock *gl;
        LIST_HEAD(skipped);
        LIST_HEAD(dispose);
+       long freed = 0;
 
        spin_lock(&lru_lock);
-       while(nr && !list_empty(&lru_list)) {
+       while ((nr-- >= 0) && !list_empty(&lru_list)) {
                gl = list_entry(lru_list.next, struct gfs2_glock, gl_lru);
 
                /* Test for being demotable */
                if (!test_and_set_bit(GLF_LOCK, &gl->gl_flags)) {
                        list_move(&gl->gl_lru, &dispose);
                        atomic_dec(&lru_count);
-                       nr--;
+                       freed++;
                        continue;
                }
 
@@ -1452,23 +1452,28 @@ static void gfs2_scan_glock_lru(int nr)
        if (!list_empty(&dispose))
                gfs2_dispose_glock_lru(&dispose);
        spin_unlock(&lru_lock);
+
+       return freed;
 }
 
-static int gfs2_shrink_glock_memory(struct shrinker *shrink,
-                                   struct shrink_control *sc)
+static unsigned long gfs2_glock_shrink_scan(struct shrinker *shrink,
+                                           struct shrink_control *sc)
 {
-       if (sc->nr_to_scan) {
-               if (!(sc->gfp_mask & __GFP_FS))
-                       return -1;
-               gfs2_scan_glock_lru(sc->nr_to_scan);
-       }
+       if (!(sc->gfp_mask & __GFP_FS))
+               return SHRINK_STOP;
+       return gfs2_scan_glock_lru(sc->nr_to_scan);
+}
 
-       return (atomic_read(&lru_count) / 100) * sysctl_vfs_cache_pressure;
+static unsigned long gfs2_glock_shrink_count(struct shrinker *shrink,
+                                            struct shrink_control *sc)
+{
+       return vfs_pressure_ratio(atomic_read(&lru_count));
 }
 
 static struct shrinker glock_shrinker = {
-       .shrink = gfs2_shrink_glock_memory,
        .seeks = DEFAULT_SEEKS,
+       .count_objects = gfs2_glock_shrink_count,
+       .scan_objects = gfs2_glock_shrink_scan,
 };
 
 /**
@@ -1488,7 +1493,7 @@ static void examine_bucket(glock_examiner examiner, const struct gfs2_sbd *sdp,
 
        rcu_read_lock();
        hlist_bl_for_each_entry_rcu(gl, pos, head, gl_list) {
-               if ((gl->gl_sbd == sdp) && atomic_read(&gl->gl_ref))
+               if ((gl->gl_sbd == sdp) && atomic_inc_not_zero(&gl->gl_ref))
                        examiner(gl);
        }
        rcu_read_unlock();
@@ -1508,18 +1513,17 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)
  * thaw_glock - thaw out a glock which has an unprocessed reply waiting
  * @gl: The glock to thaw
  *
- * N.B. When we freeze a glock, we leave a ref to the glock outstanding,
- * so this has to result in the ref count being dropped by one.
  */
 
 static void thaw_glock(struct gfs2_glock *gl)
 {
        if (!test_and_clear_bit(GLF_FROZEN, &gl->gl_flags))
-               return;
+               goto out;
        set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
-       gfs2_glock_hold(gl);
-       if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
+       if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) {
+out:
                gfs2_glock_put(gl);
+       }
 }
 
 /**
@@ -1536,7 +1540,6 @@ static void clear_glock(struct gfs2_glock *gl)
        if (gl->gl_state != LM_ST_UNLOCKED)
                handle_callback(gl, LM_ST_UNLOCKED, 0, false);
        spin_unlock(&gl->gl_spin);
-       gfs2_glock_hold(gl);
        if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
                gfs2_glock_put(gl);
 }