Whamcloud - gitweb
LU-2227 build: fix 'memory illegal access' errors
[fs/lustre-release.git] / lustre / quota / qsd_lib.c
index 2514a63..0a7e75a 100644 (file)
@@ -21,7 +21,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2012 Intel, Inc.
+ * Copyright (c) 2012, Intel Corporation.
  * Use is subject to license terms.
  *
  * Author: Johann Lombardi <johann.lombardi@intel.com>
@@ -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;
@@ -229,10 +239,10 @@ static int qsd_conn_callback(void *data)
        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.
@@ -352,17 +362,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 */
@@ -401,7 +410,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,
@@ -411,6 +420,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)
@@ -436,17 +455,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) {
@@ -476,11 +487,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) {
@@ -534,18 +551,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);
@@ -572,9 +591,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,
@@ -620,12 +639,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);
 
@@ -657,14 +676,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 "
@@ -683,7 +711,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);
@@ -692,7 +720,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",
@@ -721,9 +749,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) {
@@ -733,7 +761,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);