Whamcloud - gitweb
b=21433 Add debug information for quota_setdq/quota_chkdq.
[fs/lustre-release.git] / lustre / quota / quota_interface.c
index 20471a1..9555820 100644 (file)
@@ -78,7 +78,7 @@ static int filter_quota_setup(struct obd_device *obd)
 
         init_rwsem(&obt->obt_rwsem);
         obt->obt_qfmt = LUSTRE_QUOTA_V2;
-        atomic_set(&obt->obt_quotachecking, 1);
+        sema_init(&obt->obt_quotachecking, 1);
         rc = qctxt_init(obd, NULL);
         if (rc)
                 CERROR("initialize quota context failed! (rc:%d)\n", rc);
@@ -110,7 +110,7 @@ static int filter_quota_setinfo(struct obd_device *obd, void *data)
                         CDEBUG(D_WARNING, "%s: lqc_import(%p) of obd(%p) was "
                                "activated already.\n", obd->obd_name, imp, obd);
                 else
-                        CDEBUG(D_ERROR, "%s: lqc_import(%p:%p) of obd(%p) was "
+                        CERROR("%s: lqc_import(%p:%p) of obd(%p) was "
                                "activated by others.\n", obd->obd_name,
                                qctxt->lqc_import, imp, obd);
         } else {
@@ -164,7 +164,7 @@ static int filter_quota_enforce(struct obd_device *obd, unsigned int ignore)
 {
         ENTRY;
 
-        if (!sb_any_quota_enabled(obd->u.obt.obt_sb))
+        if (!ll_sb_any_quota_active(obd->u.obt.obt_sb))
                 RETURN(0);
 
         if (ignore) {
@@ -186,14 +186,12 @@ static int filter_quota_getflag(struct obd_device *obd, struct obdo *oa)
         struct obd_quotactl *oqctl;
         ENTRY;
 
-        if (!sb_any_quota_enabled(obt->obt_sb))
+        if (!ll_sb_any_quota_active(obt->obt_sb))
                 RETURN(0);
 
         OBD_ALLOC_PTR(oqctl);
-        if (!oqctl) {
-                CERROR("Not enough memory!");
+        if (!oqctl)
                 RETURN(-ENOMEM);
-        }
 
         /* set over quota flags for a uid/gid */
         oa->o_valid |= OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA;
@@ -206,6 +204,12 @@ static int filter_quota_getflag(struct obd_device *obd, struct obdo *oa)
                                        qctxt, 0);
                 if (lqs == NULL || 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);
                         break;
                 } else {
                         spin_lock(&lqs->lqs_lock);
@@ -236,14 +240,22 @@ static int filter_quota_getflag(struct obd_device *obd, struct obdo *oa)
                                 rc = err;
                         oa->o_valid &= ~((cnt == USRQUOTA) ? OBD_MD_FLUSRQUOTA :
                                                              OBD_MD_FLGRPQUOTA);
+                        CDEBUG(D_QUOTA, "fsfilt getquota for %s %d failed, "
+                               "(rc = %d)\n",
+                               cnt == USRQUOTA ? "user" : "group",
+                               cnt == USRQUOTA ? oa->o_uid : oa->o_gid, err);
                         continue;
                 }
 
                 if (oqctl->qc_dqblk.dqb_bhardlimit &&
                    (toqb(oqctl->qc_dqblk.dqb_curspace) >=
-                    oqctl->qc_dqblk.dqb_bhardlimit))
+                    oqctl->qc_dqblk.dqb_bhardlimit)) {
                         oa->o_flags |= (cnt == USRQUOTA) ?
                                 OBD_FL_NO_USRQUOTA : OBD_FL_NO_GRPQUOTA;
+                        CDEBUG(D_QUOTA, "out of quota for %s %d\n",
+                               cnt == USRQUOTA ? "user" : "group",
+                               cnt == USRQUOTA ? oa->o_uid : oa->o_gid);
+                }
         }
         OBD_FREE_PTR(oqctl);
         RETURN(rc);
@@ -264,10 +276,6 @@ static int quota_check_common(struct obd_device *obd, const unsigned int id[],
         int rc = 0, rc2[2] = { 0, 0 };
         ENTRY;
 
-        CLASSERT(MAXQUOTAS < 4);
-        if (!sb_any_quota_enabled(qctxt->lqc_sb))
-                RETURN(rc);
-
         spin_lock(&qctxt->lqc_lock);
         if (!qctxt->lqc_valid){
                 spin_unlock(&qctxt->lqc_lock);
@@ -313,9 +321,9 @@ static int quota_check_common(struct obd_device *obd, const unsigned int id[],
                                         rc = fsfilt_get_mblk(obd, qctxt->lqc_sb,
                                                              &mb, inode,frags);
                                         if (rc)
-                                                CDEBUG(D_ERROR,
-                                                       "can't get extra "
-                                                       "meta blocks.\n");
+                                                CERROR("%s: can't get extra "
+                                                       "meta blocks\n",
+                                                       obd->obd_name);
                                         else
                                                 pending[i] += mb;
                                 }
@@ -379,8 +387,30 @@ static int quota_check_common(struct obd_device *obd, const unsigned int id[],
                 RETURN(rc);
 }
 
-static int quota_chk_acq_common(struct obd_device *obd, const unsigned int id[],
-                                int pending[], int count, quota_acquire acquire,
+int quota_is_set(struct obd_device *obd, const unsigned int id[], int flag)
+{
+        struct lustre_qunit_size *lqs;
+        int i, q_set = 0;
+
+        if (!ll_sb_any_quota_active(obd->u.obt.obt_qctxt.lqc_sb))
+                RETURN(0);
+
+        for (i = 0; i < MAXQUOTAS; i++) {
+                lqs = quota_search_lqs(LQS_KEY(i, id[i]),
+                                       &obd->u.obt.obt_qctxt, 0);
+                if (lqs && !IS_ERR(lqs)) {
+                        if (lqs->lqs_flags & flag)
+                                q_set = 1;
+                        lqs_putref(lqs);
+                }
+        }
+
+        return q_set;
+}
+
+static int quota_chk_acq_common(struct obd_device *obd, struct obd_export *exp,
+                                const unsigned int id[], int pending[],
+                                int count, quota_acquire acquire,
                                 struct obd_trans_info *oti, int isblk,
                                 struct inode *inode, int frags)
 {
@@ -392,6 +422,15 @@ static int quota_chk_acq_common(struct obd_device *obd, const unsigned int id[],
         int rc = 0, cycle = 0, count_err = 1;
         ENTRY;
 
+        if (!quota_is_set(obd, id, isblk ? QB_SET : QI_SET))
+                RETURN(0);
+
+        if (isblk && (exp->exp_failed || exp->exp_abort_active_req))
+                /* If the client has been evicted or if it
+                 * timed out and tried to reconnect already,
+                 * abort the request immediately */
+                RETURN(-ENOTCONN);
+
         CDEBUG(D_QUOTA, "check quota for %s\n", obd->obd_name);
         pending[USRQUOTA] = pending[GRPQUOTA] = 0;
         /* Unfortunately, if quota master is too busy to handle the
@@ -441,6 +480,18 @@ static int quota_chk_acq_common(struct obd_device *obd, const unsigned int id[],
                         break;
                 }
 
+                /* Related quota has been disabled by master, but enabled by
+                 * slave, do not try again. */
+                if (unlikely(rc == -ESRCH)) {
+                        CERROR("mismatched quota configuration, stop try.\n");
+                        break;
+                }
+
+                if (isblk && (exp->exp_failed || exp->exp_abort_active_req))
+                        /* The client has been evicted or tried to
+                         * to reconnect already, abort the request */
+                        RETURN(-ENOTCONN);
+
                 /* -EBUSY and others, wait a second and try again */
                 if (rc < 0) {
                         cfs_waitq_t        waitq;
@@ -458,7 +509,7 @@ static int quota_chk_acq_common(struct obd_device *obd, const unsigned int id[],
                         l_wait_event(waitq, 0, &lwi);
                 }
 
-                if (rc < 0 || cycle % 10 == 2) {
+                if (rc < 0 || cycle % 10 == 0) {
                         spin_lock(&last_print_lock);
                         if (last_print == 0 ||
                             cfs_time_before((last_print + cfs_time_seconds(30)),
@@ -484,6 +535,8 @@ static int quota_chk_acq_common(struct obd_device *obd, const unsigned int id[],
                                     LQUOTA_WAIT_FOR_CHK_INO,
                             timediff);
 
+        if (rc > 0)
+                rc = 0;
         RETURN(rc);
 }
 
@@ -504,7 +557,7 @@ static int quota_pending_commit(struct obd_device *obd, const unsigned int id[],
 
         CDEBUG(D_QUOTA, "commit pending quota for  %s\n", obd->obd_name);
         CLASSERT(MAXQUOTAS < 4);
-        if (!sb_any_quota_enabled(qctxt->lqc_sb))
+        if (!ll_sb_any_quota_active(qctxt->lqc_sb))
                 RETURN(0);
 
         do_gettimeofday(&work_start);
@@ -599,12 +652,13 @@ static int mds_quota_setup(struct obd_device *obd)
         init_rwsem(&obt->obt_rwsem);
         obt->obt_qfmt = LUSTRE_QUOTA_V2;
         mds->mds_quota_info.qi_version = LUSTRE_QUOTA_V2;
-        atomic_set(&obt->obt_quotachecking, 1);
+        sema_init(&obt->obt_quotachecking, 1);
         /* initialize quota master and quota context */
         sema_init(&mds->mds_qonoff_sem, 1);
         rc = qctxt_init(obd, dqacq_handler);
         if (rc) {
-                CERROR("initialize quota context failed! (rc:%d)\n", rc);
+                CERROR("%s: initialize quota context failed! (rc:%d)\n",
+                       obd->obd_name, rc);
                 RETURN(rc);
         }
         mds->mds_quota = 1;
@@ -768,6 +822,9 @@ int osc_quota_chkdq(struct client_obd *cli, const unsigned int qid[])
         }
         spin_unlock(&qinfo_list_lock);
 
+        if (rc == NO_QUOTA)
+                CDEBUG(D_QUOTA, "chkdq found noquota for %s %d\n",
+                       cnt == USRQUOTA ? "user" : "group", id);
         RETURN(rc);
 }
 
@@ -792,26 +849,32 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[],
                     (flags & OBD_FL_NO_USRQUOTA) : (flags & OBD_FL_NO_GRPQUOTA);
 
                 oqi = alloc_qinfo(cli, id, cnt);
-                if (oqi) {
-                        spin_lock(&qinfo_list_lock);
-
-                        old = find_qinfo(cli, id, cnt);
-                        if (old && !noquota)
-                                remove_qinfo_hash(old);
-                        else if (!old && noquota)
-                                insert_qinfo_hash(oqi);
-
-                        spin_unlock(&qinfo_list_lock);
-
-                        if (old || !noquota)
-                                free_qinfo(oqi);
-                        if (old && !noquota)
-                                free_qinfo(old);
-                } else {
-                        CERROR("not enough mem!\n");
+                if (!oqi) {
                         rc = -ENOMEM;
+                        CDEBUG(D_QUOTA, "setdq for %s %d failed, (rc = %d)\n",
+                               cnt == USRQUOTA ? "user" : "group", id, rc);
                         break;
                 }
+
+                spin_lock(&qinfo_list_lock);
+                old = find_qinfo(cli, id, cnt);
+                if (old && !noquota)
+                        remove_qinfo_hash(old);
+                else if (!old && noquota)
+                        insert_qinfo_hash(oqi);
+                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);
         }
 
         RETURN(rc);