* GPL HEADER END
*/
/*
- * Copyright (c) 2012 Intel, Inc.
+ * Copyright (c) 2012, Intel Corporation.
* Use is subject to license terms.
*
* Author: Johann Lombardi <johann.lombardi@intel.com>
* a given ID.
*/
-#ifndef EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
-
#define DEBUG_SUBSYSTEM S_LQUOTA
#include <obd_class.h>
}
static inline void qpi_putref(const struct lu_env *env,
- struct qmt_pool_info *pool)
+ struct qmt_pool_info *pool)
{
LASSERT(atomic_read(&pool->qpi_ref) > 0);
if (cfs_atomic_dec_and_test(&pool->qpi_ref))
/* 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]))
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;
+ dt_obj_version_t version;
cfs_list_t *pos;
int rc = 0, qtype;
ENTRY;
/* 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->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,
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 */
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, lqe);
+ }
+
/* 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);
}