From f71bf0a85d75f74594946db4b7f43108db3d9f5a Mon Sep 17 00:00:00 2001
From: yury <yury>
Date: Mon, 10 Sep 2007 14:00:20 +0000
Subject: [PATCH] - fixed bug in ldlm_cancel_lru_local(). It should cancel
 locks according to SLV only in the case of passed zero @count. If @count is
 not zero - cancel requested number of locks regardless SLV. Found by failure
 of sanityN test_20; - raise error and return -EINVAL if ldlm_cancel_lru() did
 not cancel requested number of locks in case of sync cancel if lru resize is
 supported.

---
 lustre/ldlm/ldlm_request.c  | 33 ++++++++++++++++++---------------
 lustre/ldlm/ldlm_resource.c | 10 +++++++++-
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c
index 4dbe099573..7933e50674 100644
--- a/lustre/ldlm/ldlm_request.c
+++ b/lustre/ldlm/ldlm_request.c
@@ -1047,22 +1047,25 @@ int ldlm_cancel_lru_local(struct ldlm_namespace *ns, struct list_head *cancels,
                         if (count != 0 && added > count)
                                 break;
 
-                        /* Calculate lv for every lock. */
-                        spin_lock(&pl->pl_lock);
-                        slv = ldlm_pool_get_slv(pl);
-                        lvf = atomic_read(&pl->pl_lock_volume_factor);
-                        spin_unlock(&pl->pl_lock);
-
-                        la = cfs_duration_sec(cfs_time_sub(cur, 
-                                                           lock->l_last_used));
-                        if (la == 0)
-                                la = 1;
+                        /* Cancel locks by lru only in the case of count == 0. */
+                        if (count == 0) {
+                                /* Calculate lv for every lock. */
+                                spin_lock(&pl->pl_lock);
+                                slv = ldlm_pool_get_slv(pl);
+                                lvf = atomic_read(&pl->pl_lock_volume_factor);
+                                spin_unlock(&pl->pl_lock);
+
+                                la = cfs_duration_sec(cfs_time_sub(cur, 
+                                                      lock->l_last_used));
+                                if (la == 0)
+                                        la = 1;
                                 
-                        /* Stop when slv is not yet come from server or lv is 
-                         * smaller than it is. */
-                        lv = lvf * la * unused;
-                        if (slv == 1 || lv < slv)
-                                break;
+                                /* Stop when slv is not yet come from server or 
+                                 * lv is smaller than it is. */
+                                lv = lvf * la * unused;
+                                if (slv == 1 || lv < slv)
+                                        break;
+                        }
                 } else {
                         if ((added >= count) && 
                             (!(flags & LDLM_CANCEL_AGED) ||
diff --git a/lustre/ldlm/ldlm_resource.c b/lustre/ldlm/ldlm_resource.c
index ac082e7dfe..78ad0859a3 100644
--- a/lustre/ldlm/ldlm_resource.c
+++ b/lustre/ldlm/ldlm_resource.c
@@ -140,8 +140,16 @@ static int lprocfs_wr_lru_size(struct file *file, const char *buffer,
                        "dropping all unused locks from namespace %s\n",
                        ns->ns_name);
                 if (ns_connect_lru_resize(ns)) {
+                        int canceled, unused  = ns->ns_nr_unused;
+                        
                         /* Try to cancel all @ns_nr_unused locks. */
-                        ldlm_cancel_lru(ns, ns->ns_nr_unused, LDLM_SYNC);
+                        canceled = ldlm_cancel_lru(ns, unused, LDLM_SYNC);
+                        if (canceled < unused) {
+                                CERROR("not all requested locks are canceled, "
+                                       "requested: %d, canceled: %d\n", unused, 
+                                       canceled);
+                                return -EINVAL;
+                        }
                 } else {
                         tmp = ns->ns_max_unused;
                         ns->ns_max_unused = 0;
-- 
GitLab