* GPL HEADER END
*/
/*
- * Copyright (c) 2012, 2015, Intel Corporation.
+ * Copyright (c) 2012, 2017, Intel Corporation.
* Use is subject to license terms.
*
* Author: Johann Lombardi <johann.lombardi@intel.com>
*
* \param env - is the environment passed by the caller
* \param dev - is the dt_device storing the slave index object
+ * \param pool - is the pool type, either LQUOTA_RES_MD or LQUOTA_RES_DT
* \param type - is the quota type, either USRQUOTA or GRPQUOTA
*/
static struct dt_object *quota_obj_lookup(const struct lu_env *env,
- struct dt_device *dev, int type)
+ struct dt_device *dev, int pool,
+ int type)
{
struct lquota_thread_info *qti = lquota_info(env);
struct dt_object *obj = NULL;
+ int is_md;
ENTRY;
+ is_md = lu_device_is_md(dev->dd_lu_dev.ld_site->ls_top_dev);
+ if ((is_md && pool == LQUOTA_RES_MD) ||
+ (!is_md && pool == LQUOTA_RES_DT))
+ qti->qti_fid.f_oid = qtype2slv_oid(type);
+ else
+ qti->qti_fid.f_oid = pool << 16 | qtype2slv_oid(type);
+
qti->qti_fid.f_seq = FID_SEQ_QUOTA;
- qti->qti_fid.f_oid = qtype2slv_oid(type);
qti->qti_fid.f_ver = 0;
/* lookup the quota object */
{
struct lquota_thread_info *qti = lquota_info(env);
__u64 key;
- struct dt_object *obj;
+ struct dt_object *obj, *obj_aux = NULL;
struct obd_dqblk *dqblk = &oqctl->qc_dqblk;
int rc;
ENTRY;
RETURN(-EOPNOTSUPP);
}
- if (oqctl->qc_type < 0 || oqctl->qc_type >= MAXQUOTAS)
- /* no support for directory quota yet */
+ if (oqctl->qc_type < 0 || oqctl->qc_type >= LL_MAXQUOTAS)
RETURN(-EOPNOTSUPP);
/* qc_id is a 32-bit field while a key has 64 bits */
/* Step 2: collect enforcement information */
- obj = quota_obj_lookup(env, dev, oqctl->qc_type);
+ if (lu_device_is_md(dev->dd_lu_dev.ld_site->ls_top_dev))
+ obj = quota_obj_lookup(env, dev, LQUOTA_RES_MD, oqctl->qc_type);
+ else
+ obj = quota_obj_lookup(env, dev, LQUOTA_RES_DT, oqctl->qc_type);
+
if (IS_ERR(obj))
RETURN(0);
if (obj->do_index_ops == NULL)
if (lu_device_is_md(dev->dd_lu_dev.ld_site->ls_top_dev)) {
dqblk->dqb_ihardlimit = qti->qti_slv_rec.qsr_granted;
dqblk->dqb_bhardlimit = 0;
+
+ obj_aux = quota_obj_lookup(env, dev, LQUOTA_RES_DT,
+ oqctl->qc_type);
+ if (IS_ERR(obj_aux)) {
+ obj_aux = NULL;
+ GOTO(out, rc = 0);
+ }
+
+ if (obj_aux->do_index_ops == NULL)
+ GOTO(out, rc = 0);
+
+ memset(&qti->qti_slv_rec, 0, sizeof(qti->qti_slv_rec));
+ rc = dt_lookup(env, obj_aux, (struct dt_rec *)&qti->qti_slv_rec,
+ (struct dt_key *)&key);
+ if (rc < 0 && rc != -ENOENT)
+ GOTO(out, rc = 0);
+
+ dqblk->dqb_bhardlimit = qti->qti_slv_rec.qsr_granted;
} else {
dqblk->dqb_ihardlimit = 0;
dqblk->dqb_bhardlimit = qti->qti_slv_rec.qsr_granted;
GOTO(out, rc = 0);
out:
dt_object_put(env, obj);
+ if (obj_aux != NULL)
+ dt_object_put(env, obj_aux);
return rc;
}
EXPORT_SYMBOL(lquotactl_slv);
/**
* Helper routine returning the FID associated with the global index storing
- * quota settings for the storage pool \pool_id, resource type \pool_type and
+ * quota settings for default storage pool, resource type \pool_type and
* the quota type \quota_type.
*/
-void lquota_generate_fid(struct lu_fid *fid, int pool_id, int pool_type,
- int quota_type)
+void lquota_generate_fid(struct lu_fid *fid, int pool_type, int quota_type)
{
__u8 lqtype = qtype2lqtype(quota_type);
fid->f_seq = FID_SEQ_QUOTA_GLB;
- fid->f_oid = (lqtype << 24) | (pool_type << 16) | (__u16)pool_id;
+ fid->f_oid = (lqtype << 24) | (pool_type << 16);
fid->f_ver = 0;
}
/**
- * Helper routine used to extract pool ID, pool type and quota type from a
+ * Helper routine used to extract pool type and quota type from a
* given FID.
*/
-int lquota_extract_fid(const struct lu_fid *fid, int *pool_id, int *pool_type,
+int lquota_extract_fid(const struct lu_fid *fid, int *pool_type,
int *quota_type)
{
unsigned int lqtype;
if (fid->f_seq != FID_SEQ_QUOTA_GLB)
RETURN(-EINVAL);
- if (pool_id != NULL) {
- lqtype = fid->f_oid & 0xffffU;
- if (lqtype != 0)
- /* we only support pool ID 0 for the time being */
- RETURN(-ENOTSUPP);
- *pool_id = lqtype;
- }
-
if (pool_type != NULL) {
lqtype = (fid->f_oid >> 16) & 0xffU;
if (lqtype >= LQUOTA_LAST_RES)