X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fquota%2Fqsd_lib.c;h=c535f90740ed6bff4b91ecf4dc10fcff9a4e62c0;hp=cc2bd32b9d82f9e815f821a74d9f2db834bc5dc6;hb=c232a80d95849b8e776ae6b738585eacbfdc3612;hpb=1398ed438568d2a07f09a59da8b7b23ff04ed4ea diff --git a/lustre/quota/qsd_lib.c b/lustre/quota/qsd_lib.c index cc2bd32..c535f90 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,61 @@ 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); + + 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 */ @@ -188,7 +233,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 +249,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; @@ -355,6 +401,8 @@ static void qsd_qtype_fini(const struct lu_env *env, struct qsd_instance *qsd, static const char *qtype2acct_name(int qtype) { + static char unknown[24]; + switch (qtype) { case USRQUOTA: return "acct_user"; @@ -364,12 +412,14 @@ static const char *qtype2acct_name(int qtype) return "acct_project"; } - LASSERTF(0, "invalid quota type: %d", qtype); - return NULL; + snprintf(unknown, sizeof(unknown), "acct_unknown_%u", qtype); + return unknown; } static const char *qtype2glb_name(int qtype) { + static char unknown[24]; + switch (qtype) { case USRQUOTA: return "limit_user"; @@ -379,8 +429,8 @@ static const char *qtype2glb_name(int qtype) return "limit_project"; } - LASSERTF(0, "invalid quota type: %d", qtype); - return NULL; + snprintf(unknown, sizeof(unknown), "acct_unknown_%u", qtype); + return unknown; } /* @@ -425,8 +475,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); @@ -542,16 +591,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); - - 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); @@ -562,6 +601,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); @@ -596,7 +643,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; @@ -623,6 +670,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)) @@ -634,11 +682,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) { @@ -659,8 +702,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; @@ -713,12 +766,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, @@ -757,7 +808,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);