Whamcloud - gitweb
LU-4920 quota: always clear lqe_lockh on lock cancel 78/11278/2
authorLi Xi <lixi@ddn.com>
Wed, 30 Jul 2014 07:58:56 +0000 (15:58 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 14 Aug 2014 15:02:53 +0000 (15:02 +0000)
In the qsd_id_blocking_ast(), lqe_lockh should always be cleared,
otherwise, quota code will mistakenly assume the id lock is still
valid.

Lustre-change: http://review.whamcloud.com/9965/
Lustre-commit: 73ef5dcd8bcf32e4127e0011357b8bc39472cdba

Signed-off-by: Niu Yawei <yawei.niu@intel.com>
Signed-off-by: Li Xi <lixi@ddn.com>
Change-Id: I653e263176a5415ec32324479fed86d948958ef0
Reviewed-on: http://review.whamcloud.com/11278
Tested-by: Jenkins
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/quota/qsd_lock.c

index c16275d..0d90252 100644 (file)
@@ -310,7 +310,6 @@ static int qsd_id_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *de
        case LDLM_CB_CANCELING: {
                struct lu_env           *env;
                struct lquota_entry     *lqe;
-               bool                     rel = false;
 
                LDLM_DEBUG(lock, "canceling global quota lock");
                lqe = qsd_id_ast_data_get(lock, true);
@@ -319,29 +318,6 @@ static int qsd_id_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *de
 
                LQUOTA_DEBUG(lqe, "losing ID lock");
 
-               /* just local cancel (for stack clean up or eviction), don't
-                * release quota space in this case */
-               if ((lock->l_flags & LDLM_FL_LOCAL_ONLY) != 0) {
-                       lqe_putref(lqe);
-                       break;
-               }
-
-               /* allocate environment */
-               OBD_ALLOC_PTR(env);
-               if (env == NULL) {
-                       lqe_putref(lqe);
-                       rc = -ENOMEM;
-                       break;
-               }
-
-               /* initialize environment */
-               rc = lu_env_init(env, LCT_DT_THREAD);
-               if (rc) {
-                       OBD_FREE_PTR(env);
-                       lqe_putref(lqe);
-                       break;
-               }
-
                ldlm_lock2handle(lock, &lockh);
                lqe_write_lock(lqe);
                if (lustre_handle_equal(&lockh, &lqe->lqe_lockh)) {
@@ -349,21 +325,41 @@ static int qsd_id_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *de
                        qsd_set_qunit(lqe, 0);
                        memset(&lqe->lqe_lockh, 0, sizeof(lqe->lqe_lockh));
                        qsd_set_edquot(lqe, false);
-                       rel = true;
                }
                lqe_write_unlock(lqe);
 
-               /* If there is qqacq inflight, the release will be skipped
+               /* If there is dqacq inflight, the release will be skipped
                 * at this time, and triggered on dqacq completion later,
                 * which means there could be a short window that slave is
                 * holding spare grant wihtout per-ID lock. */
-               if (rel)
+
+               /* don't release quota space for local cancel (stack clean
+                * up or eviction) */
+               if (!ldlm_is_local_only(lock)) {
+                       /* allocate environment */
+                       OBD_ALLOC_PTR(env);
+                       if (env == NULL) {
+                               lqe_putref(lqe);
+                               rc = -ENOMEM;
+                               break;
+                       }
+
+                       /* initialize environment */
+                       rc = lu_env_init(env, LCT_DT_THREAD);
+                       if (rc) {
+                               OBD_FREE_PTR(env);
+                               lqe_putref(lqe);
+                               break;
+                       }
+
                        rc = qsd_adjust(env, lqe);
 
+                       lu_env_fini(env);
+                       OBD_FREE_PTR(env);
+               }
+
                /* release lqe reference grabbed by qsd_id_ast_data_get() */
                lqe_putref(lqe);
-               lu_env_fini(env);
-               OBD_FREE_PTR(env);
                break;
        }
        default: