Whamcloud - gitweb
ORNL-14: Configuration and Unit test cases
[fs/lustre-release.git] / lustre / quota / quota_interface.c
index 168f6df..fbf6ee5 100644 (file)
  * 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.
+ *
+ * Copyright (c) 2011 Whamcloud, Inc.
+ *
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -202,15 +205,17 @@ static int filter_quota_getflag(struct obd_device *obd, struct obdo *oa)
 
                 lqs = quota_search_lqs(LQS_KEY(cnt, GET_OA_ID(cnt, oa)),
                                        qctxt, 0);
-                if (lqs == NULL || IS_ERR(lqs)) {
+                if (IS_ERR(lqs)) {
                         rc = PTR_ERR(lqs);
-                        if (rc)
-                                CDEBUG(D_QUOTA, "search lqs for %s %d failed, "
-                                       "(rc = %d)\n",
-                                       cnt == USRQUOTA ? "user" : "group",
-                                       cnt == USRQUOTA ? oa->o_uid : oa->o_gid,
-                                       rc);
+                        CDEBUG(D_QUOTA, "search lqs for %s %d failed, "
+                               "(rc = %d)\n",
+                               cnt == USRQUOTA ? "user" : "group",
+                               GET_OA_ID(cnt, oa), rc);
                         break;
+                } else if (lqs == NULL) {
+                        /* continue to check group quota if the file's owner
+                         * doesn't have quota limit. LU-530 */
+                        continue;
                 } else {
                         cfs_spin_lock(&lqs->lqs_lock);
                         if (lqs->lqs_bunit_sz <= qctxt->lqc_sync_blk) {
@@ -446,17 +451,19 @@ static int quota_chk_acq_common(struct obd_device *obd, struct obd_export *exp,
                 cfs_spin_lock(&qctxt->lqc_lock);
                 if (!qctxt->lqc_import && oti) {
                         cfs_spin_unlock(&qctxt->lqc_lock);
-
-                        LASSERT(oti && oti->oti_thread &&
-                                oti->oti_thread->t_watchdog);
-
-                        lc_watchdog_disable(oti->oti_thread->t_watchdog);
+                        LASSERT(oti->oti_thread);
+                        /* The recovery thread doesn't have watchdog
+                         * attached. LU-369 */
+                        if (oti->oti_thread->t_watchdog)
+                                lc_watchdog_disable(oti->oti_thread->\
+                                                t_watchdog);
                         CDEBUG(D_QUOTA, "sleep for quota master\n");
                         l_wait_event(qctxt->lqc_wait_for_qmaster, check_qm(qctxt),
                                      &lwi);
                         CDEBUG(D_QUOTA, "wake up when quota master is back\n");
-                        lc_watchdog_touch(oti->oti_thread->t_watchdog,
-                                 CFS_GET_TIMEOUT(oti->oti_thread->t_svc));
+                        if (oti->oti_thread->t_watchdog)
+                                lc_watchdog_touch(oti->oti_thread->t_watchdog,
+                                       CFS_GET_TIMEOUT(oti->oti_thread->t_svc));
                 } else {
                         cfs_spin_unlock(&qctxt->lqc_lock);
                 }
@@ -655,7 +662,7 @@ static int mds_quota_setup(struct obd_device *obd)
         mds->mds_quota_info.qi_version = LUSTRE_QUOTA_V2;
         cfs_sema_init(&obt->obt_quotachecking, 1);
         /* initialize quota master and quota context */
-        cfs_sema_init(&mds->mds_qonoff_sem, 1);
+        cfs_init_rwsem(&mds->mds_qonoff_sem);
         rc = qctxt_init(obd, dqacq_handler);
         if (rc) {
                 CERROR("%s: initialize quota context failed! (rc:%d)\n",
@@ -704,9 +711,9 @@ static int mds_quota_fs_cleanup(struct obd_device *obd)
         memset(&oqctl, 0, sizeof(oqctl));
         oqctl.qc_type = UGQUOTA;
 
-        cfs_down(&mds->mds_qonoff_sem);
+        cfs_down_write(&mds->mds_qonoff_sem);
         mds_admin_quota_off(obd, &oqctl);
-        cfs_up(&mds->mds_qonoff_sem);
+        cfs_up_write(&mds->mds_qonoff_sem);
         RETURN(0);
 }
 
@@ -787,7 +794,7 @@ static struct osc_quota_info *alloc_qinfo(struct client_obd *cli,
         struct osc_quota_info *oqi;
         ENTRY;
 
-        OBD_SLAB_ALLOC(oqi, qinfo_cachep, CFS_ALLOC_STD, sizeof(*oqi));
+        OBD_SLAB_ALLOC(oqi, qinfo_cachep, CFS_ALLOC_IO, sizeof(*oqi));
         if(!oqi)
                 RETURN(NULL);
 
@@ -839,7 +846,7 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[],
 
 
         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-                struct osc_quota_info *oqi, *old;
+                struct osc_quota_info *oqi = NULL, *old;
 
                 if (!(valid & ((cnt == USRQUOTA) ?
                     OBD_MD_FLUSRQUOTA : OBD_MD_FLGRPQUOTA)))
@@ -849,12 +856,16 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[],
                 noquota = (cnt == USRQUOTA) ?
                     (flags & OBD_FL_NO_USRQUOTA) : (flags & OBD_FL_NO_GRPQUOTA);
 
-                oqi = alloc_qinfo(cli, id, cnt);
-                if (!oqi) {
-                        rc = -ENOMEM;
-                        CDEBUG(D_QUOTA, "setdq for %s %d failed, (rc = %d)\n",
-                               cnt == USRQUOTA ? "user" : "group", id, rc);
-                        break;
+                if (noquota) {
+                        oqi = alloc_qinfo(cli, id, cnt);
+                        if (!oqi) {
+                                rc = -ENOMEM;
+                                CDEBUG(D_QUOTA, "setdq for %s %d failed, "
+                                       "(rc = %d)\n",
+                                       cnt == USRQUOTA ? "user" : "group",
+                                       id, rc);
+                                break;
+                        }
                 }
 
                 cfs_spin_lock(&qinfo_list_lock);
@@ -865,17 +876,19 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[],
                         insert_qinfo_hash(oqi);
                 cfs_spin_unlock(&qinfo_list_lock);
 
-                if (old || !noquota)
-                        free_qinfo(oqi);
-                if (old && !noquota)
-                        free_qinfo(old);
-
                 if (old && !noquota)
                         CDEBUG(D_QUOTA, "setdq to remove for %s %d\n",
                                cnt == USRQUOTA ? "user" : "group", id);
                 else if (!old && noquota)
                         CDEBUG(D_QUOTA, "setdq to insert for %s %d\n",
                                cnt == USRQUOTA ? "user" : "group", id);
+
+                if (old) {
+                        if (noquota)
+                                free_qinfo(oqi);
+                        else
+                                free_qinfo(old);
+                }
         }
 
         RETURN(rc);