X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fquota%2Fqsd_lib.c;h=dea0cbdaff5454db2f6ffa46f7434417a483f960;hb=1b2547843817b4b7adbeb87ea9b070d9cac35c90;hp=5a8c7b02a721ebc26ce6e15dd4865809ca5ec975;hpb=9680dabde70a9ec5f211e26d7c2f2988f296f455;p=fs%2Flustre-release.git diff --git a/lustre/quota/qsd_lib.c b/lustre/quota/qsd_lib.c index 5a8c7b0..dea0cbd 100644 --- a/lustre/quota/qsd_lib.c +++ b/lustre/quota/qsd_lib.c @@ -21,7 +21,7 @@ * GPL HEADER END */ /* - * Copyright (c) 2012 Intel, Inc. + * Copyright (c) 2012, 2013, Intel Corporation. * Use is subject to license terms. * * Author: Johann Lombardi @@ -58,7 +58,7 @@ #include #include "qsd_internal.h" -cfs_mem_cache_t *upd_kmem; +struct kmem_cache *upd_kmem; struct lu_kmem_descr qsd_caches[] = { { @@ -104,16 +104,26 @@ static int lprocfs_qsd_rd_state(char *page, char **start, off_t off, qsd->qsd_is_md ? "md" : "dt", enabled, qsd->qsd_exp_valid ? "setup" : "not setup yet"); - if (qsd->qsd_prepared) + if (qsd->qsd_prepared) { + memset(enabled, 0, sizeof(enabled)); + if (qsd->qsd_type_array[USRQUOTA]->qqi_acct_obj != NULL) + strcat(enabled, "u"); + if (qsd->qsd_type_array[GRPQUOTA]->qqi_acct_obj != NULL) + strcat(enabled, "g"); + if (strlen(enabled) == 0) + strcat(enabled, "none"); rc += snprintf(page + rc, count - rc, + "space acct: %s\n" "user uptodate: glb[%d],slv[%d],reint[%d]\n" "group uptodate: glb[%d],slv[%d],reint[%d]\n", + enabled, qsd->qsd_type_array[USRQUOTA]->qqi_glb_uptodate, qsd->qsd_type_array[USRQUOTA]->qqi_slv_uptodate, qsd->qsd_type_array[USRQUOTA]->qqi_reint, qsd->qsd_type_array[GRPQUOTA]->qqi_glb_uptodate, qsd->qsd_type_array[GRPQUOTA]->qqi_slv_uptodate, qsd->qsd_type_array[GRPQUOTA]->qqi_reint); + } return rc; } @@ -146,7 +156,7 @@ static int lprocfs_qsd_wr_force_reint(struct file *file, const char *buffer, LASSERT(qsd != NULL); - cfs_write_lock(&qsd->qsd_lock); + write_lock(&qsd->qsd_lock); if (qsd->qsd_stopping) { /* don't mess up with shutdown procedure, it is already * complicated enough */ @@ -160,7 +170,7 @@ static int lprocfs_qsd_wr_force_reint(struct file *file, const char *buffer, qsd->qsd_type_array[qtype]->qqi_slv_uptodate = false; } } - cfs_write_unlock(&qsd->qsd_lock); + write_unlock(&qsd->qsd_lock); if (rc) return rc; @@ -174,10 +184,37 @@ static int lprocfs_qsd_wr_force_reint(struct file *file, const char *buffer, return rc == 0 ? count : rc; } +static int lprocfs_qsd_rd_timeout(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct qsd_instance *qsd = (struct qsd_instance *)data; + LASSERT(qsd != NULL); + + return snprintf(page, count, "%d\n", qsd_wait_timeout(qsd)); +} + +static int lprocfs_qsd_wr_timeout(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct qsd_instance *qsd = (struct qsd_instance *)data; + int timeout, rc; + LASSERT(qsd != NULL); + + rc = lprocfs_write_helper(buffer, count, &timeout); + if (rc) + return rc; + if (timeout < 0) + return -EINVAL; + + qsd->qsd_timeout = timeout; + return count; +} + static struct lprocfs_vars lprocfs_quota_qsd_vars[] = { { "info", lprocfs_qsd_rd_state, 0, 0}, { "enabled", lprocfs_qsd_rd_enabled, 0, 0}, { "force_reint", 0, lprocfs_qsd_wr_force_reint, 0}, + { "timeout", lprocfs_qsd_rd_timeout, lprocfs_qsd_wr_timeout, 0}, { NULL } }; @@ -198,14 +235,12 @@ static int qsd_conn_callback(void *data) /* qsd_exp should now be valid */ LASSERT(qsd->qsd_exp); - /* grab reference on namespace */ - ldlm_namespace_get(class_exp2obd(qsd->qsd_exp)->obd_namespace); qsd->qsd_ns = class_exp2obd(qsd->qsd_exp)->obd_namespace; - cfs_write_lock(&qsd->qsd_lock); + write_lock(&qsd->qsd_lock); /* notify that qsd_exp is now valid */ qsd->qsd_exp_valid = true; - cfs_write_unlock(&qsd->qsd_lock); + write_unlock(&qsd->qsd_lock); /* Now that the connection to master is setup, we can initiate the * reintegration procedure for quota types which are enabled. @@ -325,17 +360,16 @@ static int qsd_qtype_init(const struct lu_env *env, struct qsd_instance *qsd, thread_set_flags(&qqi->qqi_reint_thread, SVC_STOPPED); CFS_INIT_LIST_HEAD(&qqi->qqi_deferred_glb); CFS_INIT_LIST_HEAD(&qqi->qqi_deferred_slv); - memset(&qqi->qqi_lockh, 0, sizeof(qqi->qqi_lockh)); /* open accounting object */ LASSERT(qqi->qqi_acct_obj == NULL); qqi->qqi_acct_obj = acct_obj_lookup(env, qsd->qsd_dev, qtype); - if (qqi->qqi_acct_obj == NULL) { - LCONSOLE_ERROR("%s: No %s space accounting support. Please use " - "tunefs.lustre --quota option to enable quota " - "accounting.\n", - qsd->qsd_svname, QTYPE_NAME(qtype)); - GOTO(out, rc = -ENOENT); + if (IS_ERR(qqi->qqi_acct_obj)) { + CDEBUG(D_QUOTA, "%s: no %s space accounting support rc:%ld\n", + qsd->qsd_svname, QTYPE_NAME(qtype), + PTR_ERR(qqi->qqi_acct_obj)); + qqi->qqi_acct_obj = NULL; + qsd->qsd_acct_failed = true; } /* open global index copy */ @@ -374,7 +408,7 @@ static int qsd_qtype_init(const struct lu_env *env, struct qsd_instance *qsd, GOTO(out, rc = PTR_ERR(qqi->qqi_site)); } - /* register proc entry for accounting object */ + /* register proc entry for accounting & global index copy objects */ rc = lprocfs_seq_create(qsd->qsd_proc, qtype == USRQUOTA ? "acct_user" : "acct_group", 0444, &lprocfs_quota_seq_fops, @@ -384,6 +418,16 @@ static int qsd_qtype_init(const struct lu_env *env, struct qsd_instance *qsd, qsd->qsd_svname, rc); GOTO(out, rc); } + + rc = lprocfs_seq_create(qsd->qsd_proc, + qtype == USRQUOTA ? "limit_user" : "limit_group", + 0444, &lprocfs_quota_seq_fops, + qqi->qqi_glb_obj); + if (rc) { + CERROR("%s: can't add procfs entry for global index copy %d\n", + qsd->qsd_svname, rc); + GOTO(out, rc); + } EXIT; out: if (rc) @@ -409,17 +453,9 @@ void qsd_fini(const struct lu_env *env, struct qsd_instance *qsd) RETURN_EXIT; CDEBUG(D_QUOTA, "%s: initiating QSD shutdown\n", qsd->qsd_svname); - cfs_write_lock(&qsd->qsd_lock); + write_lock(&qsd->qsd_lock); qsd->qsd_stopping = true; - cfs_write_unlock(&qsd->qsd_lock); - - /* remove from the list of fsinfo */ - if (!cfs_list_empty(&qsd->qsd_link)) { - LASSERT(qsd->qsd_fsinfo != NULL); - cfs_down(&qsd->qsd_fsinfo->qfs_sem); - cfs_list_del_init(&qsd->qsd_link); - cfs_up(&qsd->qsd_fsinfo->qfs_sem); - } + write_unlock(&qsd->qsd_lock); /* remove qsd proc entry */ if (qsd->qsd_proc != NULL) { @@ -437,9 +473,7 @@ void qsd_fini(const struct lu_env *env, struct qsd_instance *qsd) qsd_stop_reint_thread(qsd->qsd_type_array[qtype]); } - /* release reference on namespace */ if (qsd->qsd_ns != NULL) { - ldlm_namespace_put(qsd->qsd_ns); qsd->qsd_ns = NULL; } @@ -449,11 +483,17 @@ void qsd_fini(const struct lu_env *env, struct qsd_instance *qsd) /* deregister connection to the quota master */ qsd->qsd_exp_valid = false; - lustre_deregister_osp_item(&qsd->qsd_exp); + lustre_deregister_lwp_item(&qsd->qsd_exp); /* release per-filesystem information */ - if (qsd->qsd_fsinfo != NULL) + if (qsd->qsd_fsinfo != NULL) { + down(&qsd->qsd_fsinfo->qfs_sem); + /* remove from the list of fsinfo */ + cfs_list_del_init(&qsd->qsd_link); + up(&qsd->qsd_fsinfo->qfs_sem); qsd_put_fsinfo(qsd->qsd_fsinfo); + qsd->qsd_fsinfo = NULL; + } /* release quota root directory */ if (qsd->qsd_root != NULL) { @@ -507,18 +547,20 @@ struct qsd_instance *qsd_init(const struct lu_env *env, char *svname, RETURN(ERR_PTR(-ENOMEM)); /* generic initializations */ - cfs_rwlock_init(&qsd->qsd_lock); + rwlock_init(&qsd->qsd_lock); CFS_INIT_LIST_HEAD(&qsd->qsd_link); thread_set_flags(&qsd->qsd_upd_thread, SVC_STOPPED); cfs_waitq_init(&qsd->qsd_upd_thread.t_ctl_waitq); CFS_INIT_LIST_HEAD(&qsd->qsd_upd_list); - cfs_spin_lock_init(&qsd->qsd_adjust_lock); + spin_lock_init(&qsd->qsd_adjust_lock); CFS_INIT_LIST_HEAD(&qsd->qsd_adjust_list); qsd->qsd_prepared = false; qsd->qsd_started = false; /* copy service name */ - strncpy(qsd->qsd_svname, svname, MAX_OBD_NAME); + if (strlcpy(qsd->qsd_svname, svname, sizeof(qsd->qsd_svname)) + >= sizeof(qsd->qsd_svname)) + GOTO(out, rc = -E2BIG); /* grab reference on osd device */ lu_device_get(&dev->dd_lu_dev); @@ -545,9 +587,9 @@ struct qsd_instance *qsd_init(const struct lu_env *env, char *svname, } /* add in the list of lquota_fsinfo */ - cfs_down(&qsd->qsd_fsinfo->qfs_sem); + down(&qsd->qsd_fsinfo->qfs_sem); list_add_tail(&qsd->qsd_link, &qsd->qsd_fsinfo->qfs_qsd_list); - cfs_up(&qsd->qsd_fsinfo->qfs_sem); + up(&qsd->qsd_fsinfo->qfs_sem); /* register procfs directory */ qsd->qsd_proc = lprocfs_register(QSD_DIR, osd_proc, @@ -593,12 +635,12 @@ int qsd_prepare(const struct lu_env *env, struct qsd_instance *qsd) if (unlikely(qsd == NULL)) RETURN(0); - cfs_read_lock(&qsd->qsd_lock); + read_lock(&qsd->qsd_lock); if (qsd->qsd_prepared) { CERROR("%s: qsd instance already prepared\n", qsd->qsd_svname); rc = -EALREADY; } - cfs_read_unlock(&qsd->qsd_lock); + read_unlock(&qsd->qsd_lock); if (rc) RETURN(rc); @@ -630,14 +672,23 @@ int qsd_prepare(const struct lu_env *env, struct qsd_instance *qsd) } /* pools successfully setup, mark the qsd as prepared */ - cfs_write_lock(&qsd->qsd_lock); + write_lock(&qsd->qsd_lock); qsd->qsd_prepared = true; - cfs_write_unlock(&qsd->qsd_lock); + write_unlock(&qsd->qsd_lock); /* start reintegration thread for each type, if required */ for (qtype = USRQUOTA; qtype < MAXQUOTAS; qtype++) { struct qsd_qtype_info *qqi = qsd->qsd_type_array[qtype]; + if (qsd_type_enabled(qsd, qtype) && qsd->qsd_acct_failed) { + LCONSOLE_ERROR("%s: can't enable quota enforcement " + "since space accounting isn't functional" + ". Please run tunefs.lustre --quota on " + "an unmounted filesystem if not done " + "already\n", qsd->qsd_svname); + break; + } + rc = qsd_start_reint_thread(qqi); if (rc) { CERROR("%s: failed to start reint thread for type %s " @@ -656,7 +707,7 @@ int qsd_prepare(const struct lu_env *env, struct qsd_instance *qsd) } /* generate osp name */ - rc = tgt_name2ospname((char *)qsd->qsd_svname, qti->qti_buf); + rc = tgt_name2lwpname((char *)qsd->qsd_svname, qti->qti_buf); if (rc) { CERROR("%s: failed to generate ospname (%d)\n", qsd->qsd_svname, rc); @@ -665,7 +716,7 @@ int qsd_prepare(const struct lu_env *env, struct qsd_instance *qsd) /* the connection callback will start the reintegration * procedure if quota is enabled */ - rc = lustre_register_osp_item(qti->qti_buf, &qsd->qsd_exp, + rc = lustre_register_lwp_item(qti->qti_buf, &qsd->qsd_exp, qsd_conn_callback, (void *)qsd); if (rc) { CERROR("%s: fail to get connection to master (%d)\n", @@ -694,9 +745,9 @@ int qsd_start(const struct lu_env *env, struct qsd_instance *qsd) if (unlikely(qsd == NULL)) RETURN(0); - cfs_write_lock(&qsd->qsd_lock); + write_lock(&qsd->qsd_lock); if (!qsd->qsd_prepared) { - CERROR("%s: can't start qsd instance since it was properly " + CERROR("%s: can't start qsd instance since it wasn't properly " "initialized\n", qsd->qsd_svname); rc = -EFAULT; } else if (qsd->qsd_started) { @@ -706,7 +757,7 @@ int qsd_start(const struct lu_env *env, struct qsd_instance *qsd) /* notify that the qsd_instance is now started */ qsd->qsd_started = true; } - cfs_write_unlock(&qsd->qsd_lock); + write_unlock(&qsd->qsd_lock); if (rc) RETURN(rc);