* GPL HEADER END
*/
/*
- * Copyright (c) 2012, 2016, Intel Corporation.
+ * Copyright (c) 2012, 2017, Intel Corporation.
* Use is subject to license terms.
*
* Author: Johann Lombardi <johann.lombardi@intel.com>
if (strlen(enabled) == 0)
strcat(enabled, "none");
+ /* TODO: further pool ID should be removed or
+ * replaced with pool Name */
seq_printf(m, "target name: %s\n"
"pool ID: %d\n"
"type: %s\n"
"quota enabled: %s\n"
"conn to master: %s\n",
- qsd->qsd_svname, qsd->qsd_pool_id,
+ qsd->qsd_svname, 0,
qsd->qsd_is_md ? "md" : "dt", enabled,
qsd->qsd_exp_valid ? "setup" : "not setup yet");
memset(enabled, 0, sizeof(enabled));
if (qsd_type_enabled(qsd, USRQUOTA))
- strcat(enabled, "u");
+ strncat(enabled, "u", sizeof(enabled) - strlen(enabled));
if (qsd_type_enabled(qsd, GRPQUOTA))
- strcat(enabled, "g");
+ strncat(enabled, "g", sizeof(enabled) - strlen(enabled));
if (qsd_type_enabled(qsd, PRJQUOTA))
- strncat(enabled, "p", 1);
+ strncat(enabled, "p", sizeof(enabled) - strlen(enabled));
if (strlen(enabled) == 0)
- strcat(enabled, "none");
+ strncat(enabled, "none", sizeof(enabled) - strlen(enabled));
seq_printf(m, "%s\n", enabled);
return 0;
}
-LPROC_SEQ_FOPS_RO(qsd_enabled);
+
+static ssize_t qsd_enabled_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
+{
+ struct seq_file *m = file->private_data;
+ struct qsd_instance *qsd = m->private;
+ char fsname[LUSTRE_MAXFSNAME + 1];
+ int enabled = 0;
+ char valstr[5];
+ int pool, rc;
+
+ if (count > 4)
+ return -E2BIG;
+
+ if (copy_from_user(valstr, buffer, count))
+ GOTO(out, count = -EFAULT);
+
+ valstr[sizeof(valstr) - 1] = 0;
+ if (strchr(valstr, 'u'))
+ enabled |= BIT(USRQUOTA);
+ if (strchr(valstr, 'g'))
+ enabled |= BIT(GRPQUOTA);
+ if (strchr(valstr, 'p'))
+ enabled |= BIT(PRJQUOTA);
+
+ if (enabled == 0 && strcmp(valstr, "none"))
+ GOTO(out, count = -EINVAL);
+
+ if (qsd->qsd_is_md)
+ pool = LQUOTA_RES_MD;
+ else
+ pool = LQUOTA_RES_DT;
+
+ if (server_name2fsname(qsd->qsd_svname, fsname, NULL))
+ GOTO(out, count = -EINVAL);
+
+ rc = qsd_config(valstr, fsname, pool);
+ if (rc)
+ count = rc;
+out:
+ return count;
+}
+LPROC_SEQ_FOPS(qsd_enabled);
/* force reintegration procedure to be executed.
* Used for test/debugging purpose */
}
return rc == 0 ? count : rc;
}
-LPROC_SEQ_FOPS_WO_TYPE(qsd, force_reint);
+LPROC_SEQ_FOPS_WR_ONLY(qsd, force_reint);
static int qsd_timeout_seq_show(struct seq_file *m, void *data)
{
size_t count, loff_t *off)
{
struct qsd_instance *qsd = ((struct seq_file *)file->private_data)->private;
+ time64_t timeout;
int rc;
- __s64 timeout;
- LASSERT(qsd != NULL);
- rc = lprocfs_str_to_s64(buffer, count, &timeout);
+ LASSERT(qsd != NULL);
+ rc = kstrtoll_from_user(buffer, count, 0, &timeout);
if (rc)
return rc;
- if (timeout < 0 || timeout > INT_MAX)
+
+ if (timeout < 0)
return -EINVAL;
qsd->qsd_timeout = timeout;
thread_set_flags(&qqi->qqi_reint_thread, SVC_STOPPED);
INIT_LIST_HEAD(&qqi->qqi_deferred_glb);
INIT_LIST_HEAD(&qqi->qqi_deferred_slv);
- lquota_generate_fid(&qqi->qqi_fid, qsd->qsd_pool_id,
- QSD_RES_TYPE(qsd), qtype);
+ lquota_generate_fid(&qqi->qqi_fid, QSD_RES_TYPE(qsd), qtype);
/* open accounting object */
LASSERT(qqi->qqi_acct_obj == NULL);
qsd->qsd_ns = NULL;
}
- /* free per-quota type data */
- for (qtype = USRQUOTA; qtype < LL_MAXQUOTAS; qtype++)
- qsd_qtype_fini(env, qsd, qtype);
-
- if (qsd->qsd_exp) {
- /* deregister connection to the quota master */
- qsd->qsd_exp_valid = false;
- lustre_deregister_lwp_item(&qsd->qsd_exp);
- }
-
/* release per-filesystem information */
if (qsd->qsd_fsinfo != NULL) {
mutex_lock(&qsd->qsd_fsinfo->qfs_mutex);
qsd->qsd_fsinfo = NULL;
}
+ /* free per-quota type data */
+ for (qtype = USRQUOTA; qtype < LL_MAXQUOTAS; qtype++)
+ qsd_qtype_fini(env, qsd, qtype);
+
+ /* deregister connection to the quota master */
+ qsd->qsd_exp_valid = false;
+ lustre_deregister_lwp_item(&qsd->qsd_exp);
+
/* release quota root directory */
if (qsd->qsd_root != NULL) {
dt_object_put(env, qsd->qsd_root);
*/
struct qsd_instance *qsd_init(const struct lu_env *env, char *svname,
struct dt_device *dev,
- struct proc_dir_entry *osd_proc)
+ struct proc_dir_entry *osd_proc, bool is_md)
{
struct qsd_thread_info *qti = qsd_info(env);
struct qsd_instance *qsd;
INIT_LIST_HEAD(&qsd->qsd_adjust_list);
qsd->qsd_prepared = false;
qsd->qsd_started = false;
+ qsd->qsd_is_md = is_md;
/* copy service name */
if (strlcpy(qsd->qsd_svname, svname, sizeof(qsd->qsd_svname))
lu_ref_add(&dev->dd_lu_dev.ld_reference, "qsd", qsd);
qsd->qsd_dev = dev;
- /* we only support pool ID 0 (default data or metadata pool) for the
- * time being. A different pool ID could be assigned to this target via
- * the configuration log in the future */
- qsd->qsd_pool_id = 0;
-
/* get fsname from svname */
rc = server_name2fsname(svname, qti->qti_buf, NULL);
if (rc) {
mutex_unlock(&qsd->qsd_fsinfo->qfs_mutex);
/* register procfs directory */
- qsd->qsd_proc = lprocfs_register(QSD_DIR, osd_proc,
- lprocfs_quota_qsd_vars, qsd);
+ if (qsd->qsd_is_md)
+ qsd->qsd_proc = lprocfs_register(QSD_DIR_MD, osd_proc,
+ lprocfs_quota_qsd_vars, qsd);
+ else
+ qsd->qsd_proc = lprocfs_register(QSD_DIR_DT, osd_proc,
+ lprocfs_quota_qsd_vars, qsd);
+
+ if (type == LDD_F_SV_TYPE_MDT && qsd->qsd_is_md)
+ lprocfs_add_symlink(QSD_DIR, osd_proc, "./%s", QSD_DIR_MD);
+ else if (type == LDD_F_SV_TYPE_OST && !qsd->qsd_is_md)
+ lprocfs_add_symlink(QSD_DIR, osd_proc, "./%s", QSD_DIR_DT);
+
if (IS_ERR(qsd->qsd_proc)) {
rc = PTR_ERR(qsd->qsd_proc);
qsd->qsd_proc = NULL;
/* Record whether this qsd instance is managing quota enforcement for a
* MDT (i.e. inode quota) or OST (block quota) */
- if (lu_device_is_md(qsd->qsd_dev->dd_lu_dev.ld_site->ls_top_dev)) {
- qsd->qsd_is_md = true;
+ if (qsd->qsd_is_md)
qsd->qsd_sync_threshold = LQUOTA_LEAST_QUNIT(LQUOTA_RES_MD);
- } else {
+ else
qsd->qsd_sync_threshold = LQUOTA_LEAST_QUNIT(LQUOTA_RES_DT);
- }
/* look-up on-disk directory for the quota slave */
qsd->qsd_root = lquota_disk_dir_find_create(env, qsd->qsd_dev, NULL,
". Please run tunefs.lustre --quota on "
"an unmounted filesystem if not done "
"already\n", qsd->qsd_svname);
- break;
+ continue;
}
rc = qsd_start_reint_thread(qqi);