Whamcloud - gitweb
LU-2346 quota: set default grace time
[fs/lustre-release.git] / lustre / quota / qmt_pool.c
index 3bea3d9..ad9e478 100644 (file)
@@ -273,6 +273,10 @@ static void qmt_pool_free(const struct lu_env *env, struct qmt_pool_info *pool)
        /* release per-quota type site used to manage quota entries as well as
         * references to global index files */
        for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
        /* release per-quota type site used to manage quota entries as well as
         * references to global index files */
        for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
+               /* release lqe storing grace time */
+               if (pool->qpi_grace_lqe[qtype] != NULL)
+                       lqe_putref(pool->qpi_grace_lqe[qtype]);
+
                /* release site */
                if (pool->qpi_site[qtype] != NULL &&
                    !IS_ERR(pool->qpi_site[qtype]))
                /* release site */
                if (pool->qpi_site[qtype] != NULL &&
                    !IS_ERR(pool->qpi_site[qtype]))
@@ -449,8 +453,10 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt,
                     struct dt_object *qmt_root)
 {
        struct qmt_thread_info  *qti = qmt_info(env);
                     struct dt_object *qmt_root)
 {
        struct qmt_thread_info  *qti = qmt_info(env);
+       struct lquota_glb_rec   *rec = &qti->qti_glb_rec;
        struct qmt_pool_info    *pool;
        struct dt_device        *dev = NULL;
        struct qmt_pool_info    *pool;
        struct dt_device        *dev = NULL;
+       dt_obj_version_t         version;
        cfs_list_t              *pos;
        int                      rc = 0, qtype;
        ENTRY;
        cfs_list_t              *pos;
        int                      rc = 0, qtype;
        ENTRY;
@@ -460,8 +466,9 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt,
        /* iterate over each pool in the hash and allocate a quota site for each
         * one. This involves creating a global index file on disk */
        cfs_list_for_each(pos, &qmt->qmt_pool_list) {
        /* iterate over each pool in the hash and allocate a quota site for each
         * one. This involves creating a global index file on disk */
        cfs_list_for_each(pos, &qmt->qmt_pool_list) {
-               struct dt_object *obj;
-               int               pool_type, pool_id;
+               struct dt_object        *obj;
+               int                      pool_type, pool_id;
+               struct lquota_entry     *lqe;
 
                pool = cfs_list_entry(pos, struct qmt_pool_info,
                                      qpi_linkage);
 
                pool = cfs_list_entry(pos, struct qmt_pool_info,
                                      qpi_linkage);
@@ -500,6 +507,34 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt,
 
                        pool->qpi_glb_obj[qtype] = obj;
 
 
                        pool->qpi_glb_obj[qtype] = obj;
 
+                       version = dt_version_get(env, obj);
+                       /* set default grace time for newly created index */
+                       if (version == 0) {
+                               rec->qbr_hardlimit = 0;
+                               rec->qbr_softlimit = 0;
+                               rec->qbr_granted = 0;
+                               rec->qbr_time = pool_type == LQUOTA_RES_MD ?
+                                       MAX_IQ_TIME : MAX_DQ_TIME;
+
+                               rc = lquota_disk_write_glb(env, obj, 0, rec);
+                               if (rc) {
+                                       CERROR("%s: failed to set default "
+                                              "grace time for %s type (%d)\n",
+                                              qmt->qmt_svname,
+                                              QTYPE_NAME(qtype), rc);
+                                       RETURN(rc);
+                               }
+
+                               rc = lquota_disk_update_ver(env, dev, obj, 1);
+                               if (rc) {
+                                       CERROR("%s: failed to set initial "
+                                              "version for %s type (%d)\n",
+                                              qmt->qmt_svname,
+                                              QTYPE_NAME(qtype), rc);
+                                       RETURN(rc);
+                               }
+                       }
+
                        /* create quota entry site for this quota type */
                        pool->qpi_site[qtype] = lquota_site_alloc(env, pool,
                                                                  true, qtype,
                        /* create quota entry site for this quota type */
                        pool->qpi_site[qtype] = lquota_site_alloc(env, pool,
                                                                  true, qtype,
@@ -525,6 +560,17 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt,
                                       qmt->qmt_svname, QTYPE_NAME(qtype), rc);
                                RETURN(rc);
                        }
                                       qmt->qmt_svname, QTYPE_NAME(qtype), rc);
                                RETURN(rc);
                        }
+
+                       /* Global grace time is stored in quota settings of
+                        * ID 0. */
+                       qti->qti_id.qid_uid = 0;
+
+                       /* look-up quota entry storing grace time */
+                       lqe = lqe_locate(env, pool->qpi_site[qtype],
+                                        &qti->qti_id);
+                       if (IS_ERR(lqe))
+                               RETURN(PTR_ERR(lqe));
+                       pool->qpi_grace_lqe[qtype] = lqe;
 #ifdef LPROCFS
                        /* add procfs file to dump the global index, mostly for
                         * debugging purpose */
 #ifdef LPROCFS
                        /* add procfs file to dump the global index, mostly for
                         * debugging purpose */
@@ -633,10 +679,18 @@ struct lquota_entry *qmt_pool_lqe_lookup(const struct lu_env *env,
        if (IS_ERR(pool))
                RETURN((void *)pool);
 
        if (IS_ERR(pool))
                RETURN((void *)pool);
 
+       if (qid->qid_uid == 0) {
+               /* caller wants to access grace time, no need to look up the
+                * entry since we keep a reference on ID 0 all the time */
+               lqe = pool->qpi_grace_lqe[qtype];
+               lqe_getref(lqe);
+               GOTO(out, 0);
+       }
+
        /* now that we have the pool, let's look-up the quota entry in the
         * right quota site */
        lqe = lqe_locate(env, pool->qpi_site[qtype], qid);
        /* now that we have the pool, let's look-up the quota entry in the
         * right quota site */
        lqe = lqe_locate(env, pool->qpi_site[qtype], qid);
-
+out:
        qpi_putref(env, pool);
        RETURN(lqe);
 }
        qpi_putref(env, pool);
        RETURN(lqe);
 }