Whamcloud - gitweb
b=23196 take lov reference in lov_quota_adjust_qunit so as to avoid races
[fs/lustre-release.git] / lustre / quota / quota_adjust_qunit.c
index 6d0c262..6b1f5ca 100644 (file)
@@ -26,7 +26,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 /*
@@ -94,6 +94,7 @@ static struct lustre_qunit_size *
 quota_create_lqs(unsigned long long lqs_key, struct lustre_quota_ctxt *qctxt)
 {
         struct lustre_qunit_size *lqs = NULL;
+        cfs_hash_t *hs = NULL;
         int rc = 0;
 
         OBD_ALLOC_PTR(lqs);
@@ -121,15 +122,20 @@ quota_create_lqs(unsigned long long lqs_key, struct lustre_quota_ctxt *qctxt)
         lqs_initref(lqs);
 
         cfs_spin_lock(&qctxt->lqc_lock);
-        if (!qctxt->lqc_valid)
-                rc = -EBUSY;
-        else
-                rc = cfs_hash_add_unique(qctxt->lqc_lqs_hash,
-                                         &lqs->lqs_key, &lqs->lqs_hash);
+        if (qctxt->lqc_valid)
+                hs = cfs_hash_getref(qctxt->lqc_lqs_hash);
         cfs_spin_unlock(&qctxt->lqc_lock);
 
-        if (!rc)
+        if (hs) {
                 lqs_getref(lqs);
+                rc = cfs_hash_add_unique(qctxt->lqc_lqs_hash,
+                                         &lqs->lqs_key, &lqs->lqs_hash);
+                if (rc)
+                        lqs_putref(lqs);
+                cfs_hash_putref(hs);
+        } else {
+                rc = -EBUSY;
+        }
 
  out:
         if (rc && lqs)
@@ -345,10 +351,11 @@ int lov_quota_adjust_qunit(struct obd_export *exp,
                 RETURN(-EFAULT);
         }
 
+        obd_getref(obd);
         for (i = 0; i < lov->desc.ld_tgt_count; i++) {
                 int err;
 
-                if (!lov->lov_tgts[i]->ltd_active) {
+                if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) {
                         CDEBUG(D_HA, "ost %d is inactive\n", i);
                         continue;
                 }
@@ -361,5 +368,6 @@ int lov_quota_adjust_qunit(struct obd_export *exp,
                         continue;
                 }
         }
+        obd_putref(obd);
         RETURN(rc);
 }