Whamcloud - gitweb
LU-11775 obdclass: protect imp_sec using rwlock_t
[fs/lustre-release.git] / lustre / quota / qsd_config.c
index 26c06bb..5077861 100644 (file)
  * 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);
 
@@ -53,15 +49,15 @@ void qsd_put_fsinfo(struct qsd_fsinfo *qfs)
        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;
 }
 
@@ -92,15 +88,15 @@ struct qsd_fsinfo *qsd_get_fsinfo(char *name, bool create)
                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;
@@ -111,18 +107,96 @@ struct qsd_fsinfo *qsd_get_fsinfo(char *name, bool create)
 
        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.
@@ -131,13 +205,12 @@ out:
  */
 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);
 
@@ -151,24 +224,5 @@ int qsd_process_config(struct lustre_cfg *lcfg)
        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);
 }