* GPL HEADER END
*/
/*
- * Copyright (c) 2012 Intel, Inc.
+ * Copyright (c) 2012, 2016, 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_getref(struct qmt_pool_info *pool)
{
- cfs_atomic_inc(&pool->qpi_ref);
+ atomic_inc(&pool->qpi_ref);
}
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))
+ if (atomic_dec_and_test(&pool->qpi_ref))
qmt_pool_free(env, pool);
}
static inline void qpi_putref_locked(struct qmt_pool_info *pool)
{
- LASSERT(cfs_atomic_read(&pool->qpi_ref) > 1);
- cfs_atomic_dec(&pool->qpi_ref);
+ LASSERT(atomic_read(&pool->qpi_ref) > 1);
+ atomic_dec(&pool->qpi_ref);
}
/*
* 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);
}
-static void *qpi_hash_key(cfs_hlist_node_t *hnode)
+static void *qpi_hash_key(struct hlist_node *hnode)
{
struct qmt_pool_info *pool;
- pool = cfs_hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
+ pool = hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
return &pool->qpi_key;
}
-static int qpi_hash_keycmp(const void *key, cfs_hlist_node_t *hnode)
+static int qpi_hash_keycmp(const void *key, struct hlist_node *hnode)
{
struct qmt_pool_info *pool;
- pool = cfs_hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
+ pool = hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
return pool->qpi_key == *((__u32 *)key);
}
-static void *qpi_hash_object(cfs_hlist_node_t *hnode)
+static void *qpi_hash_object(struct hlist_node *hnode)
{
- return cfs_hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
+ return hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
}
-static void qpi_hash_get(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
+static void qpi_hash_get(struct cfs_hash *hs, struct hlist_node *hnode)
{
struct qmt_pool_info *pool;
- pool = cfs_hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
+ pool = hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
qpi_getref(pool);
}
-static void qpi_hash_put_locked(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
+static void qpi_hash_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
{
struct qmt_pool_info *pool;
- pool = cfs_hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
+ pool = hlist_entry(hnode, struct qmt_pool_info, qpi_hash);
qpi_putref_locked(pool);
}
-static void qpi_hash_exit(cfs_hash_t *hs, cfs_hlist_node_t *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,
};
/* some procfs helpers */
-static int lprocfs_qpi_rd_state(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int qpi_state_seq_show(struct seq_file *m, void *data)
{
- struct qmt_pool_info *pool = (struct qmt_pool_info *)data;
- int type, i = 0;
+ struct qmt_pool_info *pool = m->private;
+ int type;
+
+ LASSERT(pool != NULL);
+
+ seq_printf(m, "pool:\n"
+ " id: %u\n"
+ " type: %s\n"
+ " ref: %d\n"
+ " least qunit: %lu\n",
+ pool->qpi_key & 0x0000ffff,
+ RES_NAME(pool->qpi_key >> 16),
+ atomic_read(&pool->qpi_ref),
+ pool->qpi_least_qunit);
+
+ for (type = 0; type < LL_MAXQUOTAS; type++)
+ seq_printf(m, " %s:\n"
+ " #slv: %d\n"
+ " #lqe: %d\n",
+ QTYPE_NAME(type),
+ pool->qpi_slv_nr[type],
+ atomic_read(&pool->qpi_site[type]->lqs_hash->hs_count));
+ return 0;
+}
+LPROC_SEQ_FOPS_RO(qpi_state);
+
+static int qpi_soft_least_qunit_seq_show(struct seq_file *m, void *data)
+{
+ struct qmt_pool_info *pool = m->private;
LASSERT(pool != NULL);
- i = snprintf(page, count,
- "pool:\n"
- " id: %u\n"
- " type: %s\n"
- " ref: %d\n"
- " least qunit: %lu\n",
- pool->qpi_key & 0x0000ffff,
- RES_NAME(pool->qpi_key >> 16),
- cfs_atomic_read(&pool->qpi_ref),
- pool->qpi_least_qunit);
-
-
- for (type = 0; type < MAXQUOTAS; type++)
- i += snprintf(page + i, count - i,
- " %s:\n"
- " #slv: %d\n"
- " #lqe: %d\n",
- QTYPE_NAME(type),
- pool->qpi_slv_nr[type],
- cfs_atomic_read(&pool->qpi_site[type]->lqs_hash->hs_count));
-
- return i;
+ 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;
+ int qunit, rc;
+ s64 least_qunit;
+
+ 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 = lprocfs_str_to_s64(buffer, count, &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[] = {
- { "info", lprocfs_qpi_rd_state, 0, 0},
+ { .name = "info",
+ .fops = &qpi_state_fops },
+ { .name = "soft_least_qunit",
+ .fops = &qpi_soft_least_qunit_fops },
{ NULL }
};
OBD_ALLOC_PTR(pool);
if (pool == NULL)
RETURN(-ENOMEM);
- CFS_INIT_LIST_HEAD(&pool->qpi_linkage);
+ INIT_LIST_HEAD(&pool->qpi_linkage);
/* assign key used by hash functions */
pool->qpi_key = pool_id + (pool_type << 16);
/* 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);
}
/* add to qmt pool list */
- cfs_list_add_tail(&pool->qpi_linkage, &qmt->qmt_pool_list);
+ list_add_tail(&pool->qpi_linkage, &qmt->qmt_pool_list);
EXIT;
out:
if (rc)
/* 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]);
pool->qpi_qmt = NULL;
}
- LASSERT(cfs_list_empty(&pool->qpi_linkage));
+ LASSERT(list_empty(&pool->qpi_linkage));
OBD_FREE_PTR(pool);
}
void qmt_pool_fini(const struct lu_env *env, struct qmt_device *qmt)
{
struct qmt_pool_info *pool;
- cfs_list_t *pos, *n;
+ struct list_head *pos, *n;
ENTRY;
if (qmt->qmt_pool_hash == NULL)
RETURN_EXIT;
/* parse list of pool and destroy each element */
- cfs_list_for_each_safe(pos, n, &qmt->qmt_pool_list) {
- pool = cfs_list_entry(pos, struct qmt_pool_info,
- qpi_linkage);
+ list_for_each_safe(pos, n, &qmt->qmt_pool_list) {
+ pool = list_entry(pos, struct qmt_pool_info,
+ qpi_linkage);
/* remove from hash */
cfs_hash_del(qmt->qmt_pool_hash, &pool->qpi_key,
&pool->qpi_hash);
/* remove from list */
- cfs_list_del_init(&pool->qpi_linkage);
+ list_del_init(&pool->qpi_linkage);
/* release extra reference taken in qmt_pool_alloc */
qpi_putref(env, pool);
}
- LASSERT(cfs_list_empty(&qmt->qmt_pool_list));
+ LASSERT(list_empty(&qmt->qmt_pool_list));
cfs_hash_putref(qmt->qmt_pool_hash);
qmt->qmt_pool_hash = 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
}
/* initialize pool list */
- CFS_INIT_LIST_HEAD(&qmt->qmt_pool_list);
+ INIT_LIST_HEAD(&qmt->qmt_pool_list);
/* Instantiate pool master for the default data and metadata pool (both
* have pool ID equals to 0).
* 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.
*
struct qmt_pool_info *pool;
struct dt_device *dev = NULL;
dt_obj_version_t version;
- cfs_list_t *pos;
+ struct list_head *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) {
+ list_for_each(pos, &qmt->qmt_pool_list) {
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 = list_entry(pos, struct qmt_pool_info,
+ qpi_linkage);
pool_id = pool->qpi_key & 0x0000ffff;
pool_type = pool->qpi_key >> 16;
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,
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));
* 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.
* entry since we keep a reference on ID 0 all the time */
lqe = pool->qpi_grace_lqe[qtype];
lqe_getref(lqe);
- GOTO(out, 0);
+ GOTO(out, lqe);
}
/* now that we have the pool, let's look-up the quota entry in the