Whamcloud - gitweb
Branch b1_6
authorfanyong <fanyong>
Tue, 3 Feb 2009 02:34:54 +0000 (02:34 +0000)
committerfanyong <fanyong>
Tue, 3 Feb 2009 02:34:54 +0000 (02:34 +0000)
b=18135
i=tianzy
i=andrew.perepechko

Wake up all wait threads on the "lq_waitq" when "lqc_import" is invalid.

lustre/obdfilter/filter.c
lustre/quota/quota_context.c
lustre/quota/quota_interface.c
lustre/quota/quota_internal.h

index 4d923a6..e325b6a 100644 (file)
@@ -2453,6 +2453,8 @@ static int filter_disconnect(struct obd_export *exp)
                 filter_grant_sanity_check(obd, __FUNCTION__);
         filter_grant_discard(exp);
 
+        lquota_clearinfo(filter_quota_interface_ref, exp, exp->exp_obd);
+
         /* Disconnect early so that clients can't keep using export */
         rc = class_disconnect(exp);
         if (exp->exp_obd->obd_namespace != NULL)
index a7bb435..677d8f1 100644 (file)
@@ -816,25 +816,56 @@ int check_qm(struct lustre_quota_ctxt *qctxt)
         RETURN(rc);
 }
 
+/* wake up all waiting threads when lqc_import is NULL */
+void dqacq_interrupt(struct lustre_quota_ctxt *qctxt)
+{
+        struct lustre_qunit *qunit, *tmp;
+        int i;
+        ENTRY;
+
+        spin_lock(&qunit_hash_lock);
+        for (i = 0; i < NR_DQHASH; i++) {
+                list_for_each_entry_safe(qunit, tmp, &qunit_hash[i], lq_hash) {
+                        if (qunit->lq_ctxt != qctxt)
+                                continue;
+
+                        /* Wake up all waiters. Do not change lq_state.
+                         * The waiters will check lq_rc which is kept as 0
+                         * if no others change it, then the waiters will return
+                         * -EAGAIN to caller who can perform related quota
+                         * acq/rel if necessary. */
+                        wake_up_all(&qunit->lq_waitq);
+                }
+        }
+        spin_unlock(&qunit_hash_lock);
+        EXIT;
+}
+
 static int got_qunit(struct lustre_qunit *qunit)
 {
-        int rc;
+        struct lustre_quota_ctxt *qctxt = qunit->lq_ctxt;
+        int rc = 0;
         ENTRY;
 
         spin_lock(&qunit->lq_lock);
         switch (qunit->lq_state) {
         case QUNIT_IN_HASH:
         case QUNIT_RM_FROM_HASH:
-                rc = 0;
                 break;
         case QUNIT_FINISHED:
                 rc = 1;
                 break;
         default:
-                rc = 0;
                 CERROR("invalid qunit state %d\n", qunit->lq_state);
         }
         spin_unlock(&qunit->lq_lock);
+
+        if (!rc) {
+                spin_lock(&qctxt->lqc_lock);
+                rc = !qctxt->lqc_import || !qctxt->lqc_valid;
+                spin_unlock(&qctxt->lqc_lock);
+        }
+
         RETURN(rc);
 }
 
index 7aa638c..0cc9814 100644 (file)
@@ -130,18 +130,18 @@ static int filter_quota_clearinfo(struct obd_export *exp, struct obd_device *obd
 
         /* lquota may be not set up before destroying export, b=14896 */
         if (!obd->obd_set_up)
-                return 0;
+                RETURN(0);
 
         /* when exp->exp_imp_reverse is destroyed, the corresponding lqc_import
          * should be invalid b=12374 */
-        if (qctxt->lqc_import == exp->exp_imp_reverse) {
+        if (qctxt->lqc_import && qctxt->lqc_import == exp->exp_imp_reverse) {
                 spin_lock(&qctxt->lqc_lock);
                 qctxt->lqc_import = NULL;
+                spin_unlock(&qctxt->lqc_lock);
+                dqacq_interrupt(qctxt);
                 CDEBUG(D_QUOTA, "%s: lqc_import of obd(%p) is invalid now.\n",
                        obd->obd_name, obd);
-                spin_unlock(&qctxt->lqc_lock);
         }
-
         RETURN(0);
 }
 
index b4a7acc..65e89b0 100644 (file)
@@ -114,6 +114,7 @@ int compute_remquota(struct obd_device *obd,
                      struct lustre_quota_ctxt *qctxt, struct qunit_data *qdata,
                      int isblk);
 int check_qm(struct lustre_quota_ctxt *qctxt);
+void dqacq_interrupt(struct lustre_quota_ctxt *qctxt);
 /* quota_master.c */
 int lustre_dquot_init(void);
 void lustre_dquot_exit(void);