* GPL HEADER END
*/
/*
- * Copyright (c) 2012, 2013, Intel Corporation.
+ * Copyright (c) 2012, 2017, Intel Corporation.
* Use is subject to license terms.
*
* Author: Johann Lombardi <johann.lombardi@intel.com>
* Hash functions for qmt_pool_info management
*/
-static unsigned qpi_hash_hash(cfs_hash_t *hs, const void *key, unsigned mask)
+static unsigned
+qpi_hash_hash(struct cfs_hash *hs, const void *key, unsigned mask)
{
return cfs_hash_u32_hash(*((__u32 *)key), mask);
}
return hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
}
-static void qpi_hash_get(cfs_hash_t *hs, struct hlist_node *hnode)
+static void qpi_hash_get(struct cfs_hash *hs, struct hlist_node *hnode)
{
struct qmt_pool_info *pool;
pool = hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
qpi_getref(pool);
}
-static void qpi_hash_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
+static void qpi_hash_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
{
struct qmt_pool_info *pool;
pool = hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
qpi_putref_locked(pool);
}
-static void qpi_hash_exit(cfs_hash_t *hs, struct hlist_node *hnode)
+static void qpi_hash_exit(struct cfs_hash *hs, struct hlist_node *hnode)
{
CERROR("Should not have any item left!\n");
}
/* vector of hash operations */
-static cfs_hash_ops_t qpi_hash_ops = {
+static struct cfs_hash_ops qpi_hash_ops = {
.hs_hash = qpi_hash_hash,
.hs_key = qpi_hash_key,
.hs_keycmp = qpi_hash_keycmp,
atomic_read(&pool->qpi_ref),
pool->qpi_least_qunit);
- for (type = 0; type < MAXQUOTAS; type++)
+ for (type = 0; type < LL_MAXQUOTAS; type++)
seq_printf(m, " %s:\n"
" #slv: %d\n"
" #lqe: %d\n",
- QTYPE_NAME(type),
+ qtype_name(type),
pool->qpi_slv_nr[type],
atomic_read(&pool->qpi_site[type]->lqs_hash->hs_count));
}
LPROC_SEQ_FOPS_RO(qpi_state);
-static struct lprocfs_seq_vars lprocfs_quota_qpi_vars[] = {
+static int qpi_soft_least_qunit_seq_show(struct seq_file *m, void *data)
+{
+ struct qmt_pool_info *pool = m->private;
+ LASSERT(pool != NULL);
+
+ seq_printf(m, "%lu\n", pool->qpi_soft_least_qunit);
+ return 0;
+}
+
+static ssize_t
+qpi_soft_least_qunit_seq_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *off)
+{
+ struct qmt_pool_info *pool;
+ long long least_qunit;
+ int qunit, rc;
+
+ pool = ((struct seq_file *)file->private_data)->private;
+ LASSERT(pool != NULL);
+
+ /* Not tuneable for inode limit */
+ if (pool->qpi_key >> 16 != LQUOTA_RES_DT)
+ return -EINVAL;
+
+ rc = kstrtoll_from_user(buffer, count, 0, &least_qunit);
+ if (rc)
+ return rc;
+
+ /* Miminal qpi_soft_least_qunit */
+ qunit = pool->qpi_least_qunit << 2;
+ /* The value must be power of miminal qpi_soft_least_qunit, see
+ * how the qunit is adjusted in qmt_adjust_qunit(). */
+ while (qunit > 0 && qunit < least_qunit)
+ qunit <<= 2;
+ if (qunit <= 0)
+ qunit = INT_MAX & ~3;
+
+ pool->qpi_soft_least_qunit = qunit;
+ return count;
+}
+LPROC_SEQ_FOPS(qpi_soft_least_qunit);
+
+static struct lprocfs_vars lprocfs_quota_qpi_vars[] = {
{ .name = "info",
.fops = &qpi_state_fops },
+ { .name = "soft_least_qunit",
+ .fops = &qpi_soft_least_qunit_fops },
{ NULL }
};
/* set up least qunit size to use for this pool */
pool->qpi_least_qunit = LQUOTA_LEAST_QUNIT(pool_type);
+ if (pool_type == LQUOTA_RES_DT)
+ pool->qpi_soft_least_qunit = pool->qpi_least_qunit << 2;
+ else
+ pool->qpi_soft_least_qunit = pool->qpi_least_qunit;
/* create pool proc directory */
sprintf(qti->qti_buf, "%s-0x%x", RES_NAME(pool_type), pool_id);
- pool->qpi_proc = lprocfs_seq_register(qti->qti_buf, qmt->qmt_proc,
- lprocfs_quota_qpi_vars, pool);
+ pool->qpi_proc = lprocfs_register(qti->qti_buf, qmt->qmt_proc,
+ lprocfs_quota_qpi_vars, pool);
if (IS_ERR(pool->qpi_proc)) {
rc = PTR_ERR(pool->qpi_proc);
CERROR("%s: failed to create proc entry for pool %s (%d)\n",
/* release per-quota type site used to manage quota entries as well as
* references to global index files */
- for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
+ for (qtype = 0; qtype < LL_MAXQUOTAS; qtype++) {
/* release lqe storing grace time */
if (pool->qpi_grace_lqe[qtype] != NULL)
lqe_putref(pool->qpi_grace_lqe[qtype]);
/* release reference to global index */
if (pool->qpi_glb_obj[qtype] != NULL &&
!IS_ERR(pool->qpi_glb_obj[qtype]))
- lu_object_put(env, &pool->qpi_glb_obj[qtype]->do_lu);
+ dt_object_put(env, pool->qpi_glb_obj[qtype]);
}
/* release reference on pool directory */
if (pool->qpi_root != NULL && !IS_ERR(pool->qpi_root))
- lu_object_put(env, &pool->qpi_root->do_lu);
+ dt_object_put(env, pool->qpi_root);
/* release reference on the master target */
if (pool->qpi_qmt != NULL) {
* pool which are instantiated in this function.
*
* \param env - is the environment passed by the caller
- * \param qmt - is the quota master target for which we have to initializa the
+ * \param qmt - is the quota master target for which we have to initialize the
* pool configuration
*
* \retval - 0 on success, appropriate error on failure
* Set up on-disk index files associated with each pool.
*
* \param env - is the environment passed by the caller
- * \param qmt - is the quota master target for which we have to initializa the
+ * \param qmt - is the quota master target for which we have to initialize the
* pool configuration
* \param qmt_root - is the on-disk directory created for the QMT.
*
RETURN(PTR_ERR(obj));
pool->qpi_root = obj;
- for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
+ for (qtype = 0; qtype < LL_MAXQUOTAS; qtype++) {
/* Generating FID of global index in charge of storing
* settings for this quota type */
lquota_generate_fid(&qti->qti_fid, pool_id, pool_type,
&qti->qti_fid, false);
if (IS_ERR(obj)) {
rc = PTR_ERR(obj);
- CERROR("%s: failed to create glb index copy for"
- " %s type (%d)\n", qmt->qmt_svname,
- QTYPE_NAME(qtype), rc);
+ CERROR("%s: failed to create glb index copy for %s type: rc = %d\n",
+ qmt->qmt_svname, qtype_name(qtype), rc);
RETURN(rc);
}
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);
+ CERROR("%s: failed to set default grace time for %s type: rc = %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);
+ CERROR("%s: failed to set initial version for %s type: rc = %d\n",
+ qmt->qmt_svname, qtype_name(qtype), rc);
RETURN(rc);
}
}
&qmt_lqe_ops);
if (IS_ERR(pool->qpi_site[qtype])) {
rc = PTR_ERR(pool->qpi_site[qtype]);
- CERROR("%s: failed to create site for %s type "
- "(%d)\n", qmt->qmt_svname,
- QTYPE_NAME(qtype), rc);
+ CERROR("%s: failed to create site for %s type: rc = %d\n",
+ qmt->qmt_svname, qtype_name(qtype), rc);
RETURN(rc);
}
qmt_slv_cnt,
&pool->qpi_slv_nr[qtype]);
if (rc) {
- CERROR("%s: failed to scan & count slave "
- "indexes for %s type (%d)\n",
- qmt->qmt_svname, QTYPE_NAME(qtype), rc);
+ CERROR("%s: failed to scan & count slave indexes for %s type: rc = %d\n",
+ qmt->qmt_svname, qtype_name(qtype), rc);
RETURN(rc);
}
if (IS_ERR(lqe))
RETURN(PTR_ERR(lqe));
pool->qpi_grace_lqe[qtype] = lqe;
-#ifdef LPROCFS
+#ifdef CONFIG_PROC_FS
/* add procfs file to dump the global index, mostly for
* debugging purpose */
- sprintf(qti->qti_buf, "glb-%s", QTYPE_NAME(qtype));
+ snprintf(qti->qti_buf, MTI_NAME_MAXLEN,
+ "glb-%s", qtype_name(qtype));
rc = lprocfs_seq_create(pool->qpi_proc, qti->qti_buf,
0444, &lprocfs_quota_seq_fops,
obj);
/* retrieve slave fid & current object version */
memcpy(slv_fid, lu_object_fid(&slv_obj->do_lu), sizeof(*slv_fid));
*slv_ver = dt_version_get(env, slv_obj);
- lu_object_put(env, &slv_obj->do_lu);
+ dt_object_put(env, slv_obj);
if (created)
pool->qpi_slv_nr[qtype]++;
out:
* Look-up a lquota_entry in the pool hash and allocate it if not found.
*
* \param env - is the environment passed by the caller
- * \param qmt - is the quota master target for which we have to initializa the
+ * \param qmt - is the quota master target for which we have to initialize the
* pool configuration
* \param pool_id - is the 16-bit identifier of the pool
* \param pool_type - is the pool type, either LQUOTA_RES_MD or LQUOTA_RES_DT.