X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fquota%2Fqsd_lib.c;h=da1c7c84123ad04216be9ab9ebb285574a719005;hb=875252d59924ad09db8de9f0fbb611788a0b9c78;hp=f4c37e6cab112d5b95eddec757eb890aa2ebbcbe;hpb=ce8ca7d3564439285a56982430f380354b697f68;p=fs%2Flustre-release.git diff --git a/lustre/quota/qsd_lib.c b/lustre/quota/qsd_lib.c index f4c37e6..da1c7c8 100644 --- a/lustre/quota/qsd_lib.c +++ b/lustre/quota/qsd_lib.c @@ -21,7 +21,7 @@ * GPL HEADER END */ /* - * Copyright (c) 2012, 2016, Intel Corporation. + * Copyright (c) 2012, 2017, Intel Corporation. * Use is subject to license terms. * * Author: Johann Lombardi @@ -90,12 +90,14 @@ static int qsd_state_seq_show(struct seq_file *m, void *data) 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"); @@ -137,18 +139,60 @@ static int qsd_enabled_seq_show(struct seq_file *m, void *data) 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); + + 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 */ @@ -188,7 +232,7 @@ lprocfs_force_reint_seq_write(struct file *file, const char __user *buffer, } 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) { @@ -204,14 +248,15 @@ qsd_timeout_seq_write(struct file *file, const char __user *buffer, 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; @@ -429,8 +474,7 @@ static int qsd_qtype_init(const struct lu_env *env, struct qsd_instance *qsd, 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); @@ -546,14 +590,6 @@ void qsd_fini(const struct lu_env *env, struct qsd_instance *qsd) qsd->qsd_ns = 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 per-filesystem information */ if (qsd->qsd_fsinfo != NULL) { mutex_lock(&qsd->qsd_fsinfo->qfs_mutex); @@ -564,6 +600,14 @@ void qsd_fini(const struct lu_env *env, struct qsd_instance *qsd) 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); @@ -598,7 +642,7 @@ EXPORT_SYMBOL(qsd_fini); */ 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; @@ -625,6 +669,7 @@ struct qsd_instance *qsd_init(const struct lu_env *env, char *svname, 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)) @@ -636,11 +681,6 @@ struct qsd_instance *qsd_init(const struct lu_env *env, char *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) { @@ -661,8 +701,18 @@ struct qsd_instance *qsd_init(const struct lu_env *env, char *svname, 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; @@ -715,12 +765,10 @@ int qsd_prepare(const struct lu_env *env, struct qsd_instance *qsd) /* 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, @@ -759,7 +807,7 @@ int qsd_prepare(const struct lu_env *env, struct qsd_instance *qsd) ". 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);