* GPL HEADER END
*/
/*
- * Copyright (c) 2012 Intel, Inc.
+ * Copyright (c) 2012, 2014, Intel Corporation.
* Use is subject to license terms.
*
* Author: Johann Lombardi <johann.lombardi@intel.com>
* Author: Niu Yawei <yawei.niu@intel.com>
*/
-#ifndef EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
-
#define DEBUG_SUBSYSTEM S_LQUOTA
#include <obd_class.h>
-#include <lustre_param.h>
+#include <uapi/linux/lustre/lustre_param.h>
#include "qsd_internal.h"
-static CFS_LIST_HEAD(qfs_list);
+static struct list_head qfs_list = LIST_HEAD_INIT(qfs_list);
/* protect the qfs_list */
static DEFINE_SPINLOCK(qfs_list_lock);
ENTRY;
LASSERT(qfs != NULL);
- cfs_spin_lock(&qfs_list_lock);
+ spin_lock(&qfs_list_lock);
LASSERT(qfs->qfs_ref > 0);
qfs->qfs_ref--;
if (qfs->qfs_ref == 0) {
- LASSERT(cfs_list_empty(&qfs->qfs_qsd_list));
- cfs_list_del(&qfs->qfs_link);
+ LASSERT(list_empty(&qfs->qfs_qsd_list));
+ list_del(&qfs->qfs_link);
OBD_FREE_PTR(qfs);
}
- cfs_spin_unlock(&qfs_list_lock);
+ spin_unlock(&qfs_list_lock);
EXIT;
}
if (new == NULL)
RETURN(NULL);
- cfs_sema_init(&new->qfs_sem, 1);
- CFS_INIT_LIST_HEAD(&new->qfs_qsd_list);
+ mutex_init(&new->qfs_mutex);
+ INIT_LIST_HEAD(&new->qfs_qsd_list);
strcpy(new->qfs_name, name);
new->qfs_ref = 1;
}
/* search in the fsinfo list */
- cfs_spin_lock(&qfs_list_lock);
- cfs_list_for_each_entry(qfs, &qfs_list, qfs_link) {
+ spin_lock(&qfs_list_lock);
+ list_for_each_entry(qfs, &qfs_list, qfs_link) {
if (!strcmp(qfs->qfs_name, name)) {
qfs->qfs_ref++;
goto out;
if (new) {
/* not found, but we were asked to create a new one */
- cfs_list_add_tail(&new->qfs_link, &qfs_list);
+ list_add_tail(&new->qfs_link, &qfs_list);
qfs = new;
new = NULL;
}
out:
- cfs_spin_unlock(&qfs_list_lock);
+ spin_unlock(&qfs_list_lock);
if (new)
OBD_FREE_PTR(new);
RETURN(qfs);
}
+int qsd_config(char *valstr, char *fsname, int pool)
+{
+ struct qsd_fsinfo *qfs;
+ int rc, enabled = 0, old_enabled = 0;
+ bool reint = false;
+
+ ENTRY;
+ qfs = qsd_get_fsinfo(fsname, 0);
+ if (qfs == NULL) {
+ CERROR("failed to find quota filesystem information for %s\n",
+ fsname);
+ RETURN(-ENOENT);
+ }
+
+ if (strchr(valstr, 'u'))
+ enabled |= 1 << USRQUOTA;
+ if (strchr(valstr, 'g'))
+ enabled |= 1 << GRPQUOTA;
+ if (strchr(valstr, 'p'))
+ enabled |= 1 << PRJQUOTA;
+
+ mutex_lock(&qfs->qfs_mutex);
+ if (qfs->qfs_enabled[pool - LQUOTA_FIRST_RES] == enabled)
+ /* no change required */
+ GOTO(out, rc = 0);
+
+ if ((qfs->qfs_enabled[pool - LQUOTA_FIRST_RES] & enabled) != enabled)
+ reint = true;
+
+ old_enabled = qfs->qfs_enabled[pool - LQUOTA_FIRST_RES];
+ qfs->qfs_enabled[pool - LQUOTA_FIRST_RES] = enabled;
+
+ /* trigger reintegration for all qsd */
+ if (reint) {
+ struct qsd_instance *qsd;
+ struct qsd_qtype_info *qqi;
+
+ list_for_each_entry(qsd, &qfs->qfs_qsd_list, qsd_link) {
+ bool skip = false;
+ int type;
+
+ /* start reintegration only if qsd_prepare() was
+ * successfully called */
+ read_lock(&qsd->qsd_lock);
+ if (!qsd->qsd_prepared)
+ skip = true;
+ read_unlock(&qsd->qsd_lock);
+ if (skip)
+ continue;
+
+ for (type = USRQUOTA; type < LL_MAXQUOTAS; type++) {
+ qqi = qsd->qsd_type_array[type];
+ /* only trigger reintegration if this
+ * type of quota is not enabled before */
+ if ((old_enabled & 1 << type) ||
+ !(enabled & 1 << type))
+ continue;
+
+ if (qqi->qqi_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);
+ continue;
+ }
+ qsd_start_reint_thread(qqi);
+ }
+ }
+ }
+out:
+ mutex_unlock(&qfs->qfs_mutex);
+ qsd_put_fsinfo(qfs);
+ RETURN(0);
+}
+
/*
* Quota configuration handlers in charge of processing all per-filesystem quota
* parameters set via conf_param.
*/
int qsd_process_config(struct lustre_cfg *lcfg)
{
- struct qsd_fsinfo *qfs;
- char *fsname = lustre_cfg_string(lcfg, 0);
- char *cfgstr = lustre_cfg_string(lcfg, 1);
- char *keystr, *valstr;
- int rc, pool, enabled = 0;
- ENTRY;
+ char *fsname = lustre_cfg_string(lcfg, 0);
+ char *cfgstr = lustre_cfg_string(lcfg, 1);
+ char *keystr, *valstr;
+ int pool;
+ ENTRY;
CDEBUG(D_QUOTA, "processing quota parameter: fs:%s cfgstr:%s\n", fsname,
cfgstr);
else
RETURN(-EINVAL);
- qfs = qsd_get_fsinfo(fsname, 0);
- if (qfs == NULL) {
- CERROR("Fail to find quota filesystem information for %s\n",
- fsname);
- RETURN(-ENOENT);
- }
-
- if (strchr(valstr, 'u'))
- enabled |= 1 << USRQUOTA;
- if (strchr(valstr, 'g'))
- enabled |= 1 << GRPQUOTA;
-
- if (qfs->qfs_enabled[pool - LQUOTA_FIRST_RES] == enabled)
- /* no change required */
- GOTO(out, rc = 0);
-
- qfs->qfs_enabled[pool - LQUOTA_FIRST_RES] = enabled;
-out:
- qsd_put_fsinfo(qfs);
- RETURN(0);
+ return qsd_config(valstr, fsname, pool);
}