Whamcloud - gitweb
b=24188 rehash patch makes oops in quota_search_lqs
[fs/lustre-release.git] / lustre / quota / quota_check.c
index dab8a89..6732d06 100644 (file)
@@ -26,7 +26,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 /*
@@ -99,7 +99,7 @@ static int target_quotacheck_thread(void *data)
         struct lvfs_run_ctxt saved;
         int rc;
 
-        ptlrpc_daemonize("quotacheck");
+        cfs_daemonize_ctxt("quotacheck");
 
         exp = qta->qta_exp;
         obd = qta->qta_obd;
@@ -115,7 +115,7 @@ static int target_quotacheck_thread(void *data)
 
         rc = target_quotacheck_callback(exp, oqctl);
         class_export_put(exp);
-        up(qta->qta_sem);
+        cfs_up(qta->qta_sem);
         OBD_FREE_PTR(qta);
         return rc;
 }
@@ -132,7 +132,7 @@ int target_quota_check(struct obd_device *obd, struct obd_export *exp,
         if (!qta)
                 RETURN(ENOMEM);
 
-        down(&obt->obt_quotachecking);
+        cfs_down(&obt->obt_quotachecking);
 
         qta->qta_exp = exp;
         qta->qta_obd = obd;
@@ -141,20 +141,44 @@ int target_quota_check(struct obd_device *obd, struct obd_export *exp,
         qta->qta_sb = obt->obt_sb;
         qta->qta_sem = &obt->obt_quotachecking;
 
+        /* quotaoff firstly */
+        oqctl->qc_cmd = Q_QUOTAOFF;
         if (!strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME)) {
+                rc = do_mds_quota_off(obd, oqctl);
+                if (rc && rc != -EALREADY) {
+                        CERROR("off quota on MDS failed: %d\n", rc);
+                        GOTO(out, rc);
+                }
+
                 /* quota master */
                 rc = init_admin_quotafiles(obd, &qta->qta_oqctl);
                 if (rc) {
                         CERROR("init_admin_quotafiles failed: %d\n", rc);
                         GOTO(out, rc);
                 }
+        } else {
+                struct lvfs_run_ctxt saved;
+                struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt;
+
+                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+                rc = fsfilt_quotactl(obd, obt->obt_sb, oqctl);
+                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+                if (!rc) {
+                        qctxt->lqc_flags &= ~UGQUOTA2LQC(oqctl->qc_type);
+                } else if (!quota_is_off(qctxt, oqctl)) {
+                        CERROR("off quota on OSS failed: %d\n", rc);
+                        GOTO(out, rc);
+                }
         }
 
         /* we get ref for exp because target_quotacheck_callback() will use this
          * export later b=18126 */
         class_export_get(exp);
-        rc = kernel_thread(target_quotacheck_thread, qta, CLONE_VM|CLONE_FILES);
+        rc = cfs_kernel_thread(target_quotacheck_thread, qta,
+                               CLONE_VM|CLONE_FILES);
         if (rc >= 0) {
+                /* target_quotacheck_thread will drop the ref on exp and release
+                 * obt_quotachecking */
                 CDEBUG(D_INFO, "%s: target_quotacheck_thread: %d\n",
                        obd->obd_name, rc);
                 RETURN(0);
@@ -166,7 +190,7 @@ int target_quota_check(struct obd_device *obd, struct obd_export *exp,
         }
 
 out:
-        up(&obt->obt_quotachecking);
+        cfs_up(&obt->obt_quotachecking);
         OBD_FREE_PTR(qta);
         return rc;
 }
@@ -274,20 +298,32 @@ int lov_quota_check(struct obd_device *unused, struct obd_export *exp,
         int i, rc = 0;
         ENTRY;
 
+        obd_getref(obd);
+
         for (i = 0; i < lov->desc.ld_tgt_count; i++) {
-                if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) {
+                if (!lov->lov_tgts[i])
+                        continue;
+
+                if (!lov->lov_tgts[i]->ltd_active) {
                         CERROR("lov idx %d inactive\n", i);
-                        RETURN(-EIO);
+                        rc = -EIO;
+                        goto out;
                 }
         }
 
         for (i = 0; i < lov->desc.ld_tgt_count; i++) {
                 int err;
 
+                if (!lov->lov_tgts[i])
+                        continue;
+
                 err = obd_quotacheck(lov->lov_tgts[i]->ltd_exp, oqctl);
                 if (err && !rc)
                         rc = err;
         }
 
+out:
+        obd_putref(obd);
+
         RETURN(rc);
 }