Whamcloud - gitweb
LU-11585 quota: no IS_ERR() check in qsd_lqe_read
[fs/lustre-release.git] / lustre / quota / qsd_entry.c
index f66df72..4e0faac 100644 (file)
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2011, 2012, Intel, Inc.
+ * Copyright (c) 2012, 2017, Intel Corporation.
  * Use is subject to license terms.
  *
- * Author: Johann Lombardi <johann@whamcloud.com>
- * Author: Niu    Yawei    <niu@whamcloud.com>
+ * Author: Johann Lombardi <johann.lombardi@intel.com>
+ * Author: Niu    Yawei    <yawei.niu@intel.com>
  */
 
-#ifndef EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
-
 #define DEBUG_SUBSYSTEM S_LQUOTA
 
 #include "qsd_internal.h"
@@ -47,11 +43,11 @@ static void qsd_lqe_init(struct lquota_entry *lqe, void *arg)
        LASSERT(!lqe_is_master(lqe));
 
        /* initialize slave parameters */
-       cfs_rwlock_init(&lqe->lqe_lock);
+       rwlock_init(&lqe->lqe_lock);
        memset(&lqe->lqe_lockh, 0, sizeof(lqe->lqe_lockh));
        lqe->lqe_pending_write = 0;
        lqe->lqe_pending_req   = 0;
-       cfs_waitq_init(&lqe->lqe_waiters);
+       init_waitqueue_head(&lqe->lqe_waiters);
        lqe->lqe_usage    = 0;
        lqe->lqe_nopreacq = false;
 }
@@ -85,12 +81,21 @@ static int qsd_lqe_read(const struct lu_env *env, struct lquota_entry *lqe,
                lqe->lqe_enforced = false;
                break;
        case 0:
-               if (qti->qti_glb_rec.qbr_hardlimit == 0 &&
-                   qti->qti_glb_rec.qbr_softlimit == 0)
-                       /* quota isn't enforced for this use */
-                       lqe->lqe_enforced = false;
-               else
+               if (lqe->lqe_id.qid_uid == 0) {
+                       qqi->qqi_default_hardlimit =
+                                               qti->qti_glb_rec.qbr_hardlimit;
+                       qqi->qqi_default_softlimit =
+                                               qti->qti_glb_rec.qbr_softlimit;
+                       qqi->qqi_default_gracetime =
+                                               qti->qti_glb_rec.qbr_granted;
+               }
+
+               if (lqe->lqe_id.qid_uid != 0 &&
+                   (qti->qti_glb_rec.qbr_hardlimit != 0 ||
+                    qti->qti_glb_rec.qbr_softlimit != 0))
                        lqe->lqe_enforced = true;
+               else
+                       lqe->lqe_enforced = false;
                break;
        default:
                LQUOTA_ERROR(lqe, "failed to read quota entry from global "
@@ -98,6 +103,29 @@ static int qsd_lqe_read(const struct lu_env *env, struct lquota_entry *lqe,
                return rc;
        }
 
+       if (lqe->lqe_id.qid_uid != 0 &&
+           (rc == -ENOENT ||
+            (LQUOTA_FLAG(qti->qti_glb_rec.qbr_time) & LQUOTA_FLAG_DEFAULT &&
+             qti->qti_glb_rec.qbr_hardlimit == 0 &&
+             qti->qti_glb_rec.qbr_softlimit == 0))) {
+               struct lquota_entry *lqe_def;
+               union lquota_id qid = { {0} };
+
+               /* ensure the lqe storing the default quota setting loaded */
+               lqe_def = lqe_locate(env, qqi->qqi_site, &qid);
+
+               lqe->lqe_is_default = true;
+
+               if (qqi->qqi_default_hardlimit != 0 ||
+                   qqi->qqi_default_softlimit != 0) {
+                       LQUOTA_DEBUG(lqe, "enforced by default quota");
+                       lqe->lqe_enforced = true;
+               }
+
+               if (!IS_ERR(lqe_def))
+                       lqe_putref(lqe_def);
+       }
+
        /* read record from slave index copy to find out how much space is
         * currently owned by this slave */
        rc = lquota_disk_read(env, qqi->qqi_slv_obj, &lqe->lqe_id,
@@ -142,15 +170,15 @@ static void qsd_lqe_debug(struct lquota_entry *lqe, void *arg,
        struct qsd_qtype_info   *qqi = (struct qsd_qtype_info *)arg;
 
        libcfs_debug_vmsg2(msgdata, fmt, args,
-                          "qsd:%s qtype:%s id:"LPU64" enforced:%d granted:"
-                          LPU64" pending:"LPU64" waiting:"LPU64" req:%d usage:"
-                          LPU64" qunit:"LPU64" qtune:"LPU64" edquot:%d\n",
-                          qqi->qqi_qsd->qsd_svname, QTYPE_NAME(qqi->qqi_qtype),
+                          "qsd:%s qtype:%s id:%llu enforced:%d granted: %llu"
+                          " pending:%llu waiting:%llu req:%d usage: %llu"
+                          " qunit:%llu qtune:%llu edquot:%d default:%s\n",
+                          qqi->qqi_qsd->qsd_svname, qtype_name(qqi->qqi_qtype),
                           lqe->lqe_id.qid_uid, lqe->lqe_enforced,
                           lqe->lqe_granted, lqe->lqe_pending_write,
                           lqe->lqe_waiting_write, lqe->lqe_pending_req,
                           lqe->lqe_usage, lqe->lqe_qunit, lqe->lqe_qtune,
-                          lqe->lqe_edquot);
+                          lqe->lqe_edquot, lqe->lqe_is_default ? "yes" : "no");
 }
 
 /*
@@ -216,7 +244,7 @@ int qsd_refresh_usage(const struct lu_env *env, struct lquota_entry *lqe)
                RETURN(rc);
        }
 
-       LQUOTA_DEBUG(lqe, "disk usage: "LPU64, lqe->lqe_usage);
+       LQUOTA_DEBUG(lqe, "disk usage: %llu", lqe->lqe_usage);
        RETURN(0);
 }
 
@@ -265,15 +293,15 @@ int qsd_update_index(const struct lu_env *env, struct qsd_qtype_info *qqi,
                /* Update record in global index copy */
                struct lquota_glb_rec *glb_rec = (struct lquota_glb_rec *)rec;
 
-               CDEBUG(D_QUOTA, "%s: updating global index hardlimit: "LPU64", "
-                      "softlimit: "LPU64" for id "LPU64"\n",
+               CDEBUG(D_QUOTA, "%s: updating global index hardlimit: %llu, "
+                      "softlimit: %llu for id %llu\n",
                       qqi->qqi_qsd->qsd_svname, glb_rec->qbr_hardlimit,
                       glb_rec->qbr_softlimit, qid->qid_uid);
        } else {
                /* Update record in slave index copy */
                struct lquota_slv_rec *slv_rec = (struct lquota_slv_rec *)rec;
 
-               CDEBUG(D_QUOTA, "%s: update granted to "LPU64" for id "LPU64
+               CDEBUG(D_QUOTA, "%s: update granted to %llu for id %llu"
                       "\n", qqi->qqi_qsd->qsd_svname, slv_rec->qsr_granted,
                       qid->qid_uid);
        }
@@ -290,8 +318,8 @@ int qsd_update_index(const struct lu_env *env, struct qsd_qtype_info *qqi,
 out:
        dt_trans_stop(env, qqi->qqi_qsd->qsd_dev, th);
        if (rc)
-               CERROR("%s: failed to update %s index copy for id "LPU64", rc:"
-                      "%d\n", qqi->qqi_qsd->qsd_svname,
+               CERROR("%s: failed to update %s index copy for id %llu, : rc = %d\n",
+                      qqi->qqi_qsd->qsd_svname,
                       global ? "global" : "slave", qid->qid_uid, rc);
        else if (flags == LQUOTA_SET_VER)
                qsd_bump_version(qqi, ver, global);
@@ -313,31 +341,41 @@ out:
 int qsd_update_lqe(const struct lu_env *env, struct lquota_entry *lqe,
                   bool global, void *rec)
 {
-       struct qsd_qtype_info *qqi;
        ENTRY;
 
        LASSERT(lqe != NULL);
        LASSERT(!lqe_is_master(lqe));
 
-       qqi = lqe2qqi(lqe);
-
        /* updating lqe is always serialized, no locking needed. */
        if (global) {
                struct lquota_glb_rec *glb_rec = (struct lquota_glb_rec *)rec;
 
+               /* doesn't change quota enforcement if the quota entry is still
+                * using default quota. */
+               if (LQUOTA_FLAG(glb_rec->qbr_time) & LQUOTA_FLAG_DEFAULT &&
+                   glb_rec->qbr_hardlimit == 0 && glb_rec->qbr_softlimit == 0)
+                       RETURN(0);
+
+               LQUOTA_DEBUG(lqe, "the ID has been set quota, so clear the"
+                            " default quota flag");
+               lqe->lqe_is_default = false;
+
                /* change enforcement status based on new hard/soft limit */
-               lqe->lqe_enforced = (glb_rec->qbr_hardlimit ||
-                                    glb_rec->qbr_softlimit) ? true : false;
+               if (lqe->lqe_id.qid_uid != 0 && (glb_rec->qbr_hardlimit != 0 ||
+                   glb_rec->qbr_softlimit != 0))
+                       lqe->lqe_enforced = true;
+               else
+                       lqe->lqe_enforced = false;
 
-               LQUOTA_DEBUG(lqe, "updating global index hardlimit: "LPU64", "
-                            "softlimit: "LPU64"\n", glb_rec->qbr_hardlimit,
+               LQUOTA_DEBUG(lqe, "updating global index hardlimit: %llu, "
+                            "softlimit: %llu", glb_rec->qbr_hardlimit,
                             glb_rec->qbr_softlimit);
        } else {
                struct lquota_slv_rec *slv_rec = (struct lquota_slv_rec *)rec;
 
                lqe->lqe_granted = slv_rec->qsr_granted;
 
-               LQUOTA_DEBUG(lqe, "updating slave index, granted:"LPU64"",
+               LQUOTA_DEBUG(lqe, "updating slave index, granted:%llu",
                             slv_rec->qsr_granted);
        }