Whamcloud - gitweb
LU-3319 lprocfs: client side cleanups
[fs/lustre-release.git] / lustre / quota / qmt_pool.c
index 3bea3d9..df6d6fc 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>
  *                          a given ID.
  */
 
-#ifndef EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
-
 #define DEBUG_SUBSYSTEM S_LQUOTA
 
 #include <obd_class.h>
@@ -73,7 +69,7 @@ static inline void qpi_getref(struct qmt_pool_info *pool)
 }
 
 static inline void qpi_putref(const struct lu_env *env,
-                              struct qmt_pool_info *pool)
+                             struct qmt_pool_info *pool)
 {
        LASSERT(atomic_read(&pool->qpi_ref) > 0);
        if (cfs_atomic_dec_and_test(&pool->qpi_ref))
@@ -145,40 +141,38 @@ static cfs_hash_ops_t qpi_hash_ops = {
 };
 
 /* some procfs helpers */
-static int lprocfs_qpi_rd_state(char *page, char **start, off_t off,
-                               int count, int *eof, void *data)
+static int qpi_state_seq_show(struct seq_file *m, void *data)
 {
-       struct qmt_pool_info    *pool = (struct qmt_pool_info *)data;
-       int                      type, i = 0;
+       struct qmt_pool_info    *pool = m->private;
+       int                      type;
 
        LASSERT(pool != NULL);
 
-       i = snprintf(page, count,
-                    "pool:\n"
-                    "    id: %u\n"
-                    "    type: %s\n"
-                    "    ref: %d\n"
-                    "    least qunit: %lu\n",
-                    pool->qpi_key & 0x0000ffff,
-                    RES_NAME(pool->qpi_key >> 16),
-                    cfs_atomic_read(&pool->qpi_ref),
-                    pool->qpi_least_qunit);
-
+       seq_printf(m, "pool:\n"
+                  "    id: %u\n"
+                  "    type: %s\n"
+                  "    ref: %d\n"
+                  "    least qunit: %lu\n",
+                  pool->qpi_key & 0x0000ffff,
+                  RES_NAME(pool->qpi_key >> 16),
+                  cfs_atomic_read(&pool->qpi_ref),
+                  pool->qpi_least_qunit);
 
        for (type = 0; type < MAXQUOTAS; type++)
-               i += snprintf(page + i, count - i,
-                             "    %s:\n"
-                             "        #slv: %d\n"
-                             "        #lqe: %d\n",
-                             QTYPE_NAME(type),
-                             pool->qpi_slv_nr[type],
+               seq_printf(m, "    %s:\n"
+                          "        #slv: %d\n"
+                          "        #lqe: %d\n",
+                          QTYPE_NAME(type),
+                          pool->qpi_slv_nr[type],
                    cfs_atomic_read(&pool->qpi_site[type]->lqs_hash->hs_count));
 
-       return i;
+       return 0;
 }
+LPROC_SEQ_FOPS_RO(qpi_state);
 
-static struct lprocfs_vars lprocfs_quota_qpi_vars[] = {
-       { "info", lprocfs_qpi_rd_state, 0, 0},
+static struct lprocfs_seq_vars lprocfs_quota_qpi_vars[] = {
+       { .name =       "info",
+         .fops =       &qpi_state_fops },
        { NULL }
 };
 
@@ -219,8 +213,8 @@ static int qmt_pool_alloc(const struct lu_env *env, struct qmt_device *qmt,
 
        /* create pool proc directory */
        sprintf(qti->qti_buf, "%s-0x%x", RES_NAME(pool_type), pool_id);
-       pool->qpi_proc = lprocfs_register(qti->qti_buf, qmt->qmt_proc,
-                                         lprocfs_quota_qpi_vars, pool);
+       pool->qpi_proc = lprocfs_seq_register(qti->qti_buf, qmt->qmt_proc,
+                                               lprocfs_quota_qpi_vars, pool);
        if (IS_ERR(pool->qpi_proc)) {
                rc = PTR_ERR(pool->qpi_proc);
                CERROR("%s: failed to create proc entry for pool %s (%d)\n",
@@ -273,6 +267,10 @@ static void qmt_pool_free(const struct lu_env *env, struct qmt_pool_info *pool)
        /* release per-quota type site used to manage quota entries as well as
         * references to global index files */
        for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
+               /* release lqe storing grace time */
+               if (pool->qpi_grace_lqe[qtype] != NULL)
+                       lqe_putref(pool->qpi_grace_lqe[qtype]);
+
                /* release site */
                if (pool->qpi_site[qtype] != NULL &&
                    !IS_ERR(pool->qpi_site[qtype]))
@@ -449,8 +447,10 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt,
                     struct dt_object *qmt_root)
 {
        struct qmt_thread_info  *qti = qmt_info(env);
+       struct lquota_glb_rec   *rec = &qti->qti_glb_rec;
        struct qmt_pool_info    *pool;
        struct dt_device        *dev = NULL;
+       dt_obj_version_t         version;
        cfs_list_t              *pos;
        int                      rc = 0, qtype;
        ENTRY;
@@ -460,8 +460,9 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt,
        /* iterate over each pool in the hash and allocate a quota site for each
         * one. This involves creating a global index file on disk */
        cfs_list_for_each(pos, &qmt->qmt_pool_list) {
-               struct dt_object *obj;
-               int               pool_type, pool_id;
+               struct dt_object        *obj;
+               int                      pool_type, pool_id;
+               struct lquota_entry     *lqe;
 
                pool = cfs_list_entry(pos, struct qmt_pool_info,
                                      qpi_linkage);
@@ -500,6 +501,34 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt,
 
                        pool->qpi_glb_obj[qtype] = obj;
 
+                       version = dt_version_get(env, obj);
+                       /* set default grace time for newly created index */
+                       if (version == 0) {
+                               rec->qbr_hardlimit = 0;
+                               rec->qbr_softlimit = 0;
+                               rec->qbr_granted = 0;
+                               rec->qbr_time = pool_type == LQUOTA_RES_MD ?
+                                       MAX_IQ_TIME : MAX_DQ_TIME;
+
+                               rc = lquota_disk_write_glb(env, obj, 0, rec);
+                               if (rc) {
+                                       CERROR("%s: failed to set default "
+                                              "grace time for %s type (%d)\n",
+                                              qmt->qmt_svname,
+                                              QTYPE_NAME(qtype), rc);
+                                       RETURN(rc);
+                               }
+
+                               rc = lquota_disk_update_ver(env, dev, obj, 1);
+                               if (rc) {
+                                       CERROR("%s: failed to set initial "
+                                              "version for %s type (%d)\n",
+                                              qmt->qmt_svname,
+                                              QTYPE_NAME(qtype), rc);
+                                       RETURN(rc);
+                               }
+                       }
+
                        /* create quota entry site for this quota type */
                        pool->qpi_site[qtype] = lquota_site_alloc(env, pool,
                                                                  true, qtype,
@@ -525,6 +554,17 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt,
                                       qmt->qmt_svname, QTYPE_NAME(qtype), rc);
                                RETURN(rc);
                        }
+
+                       /* Global grace time is stored in quota settings of
+                        * ID 0. */
+                       qti->qti_id.qid_uid = 0;
+
+                       /* look-up quota entry storing grace time */
+                       lqe = lqe_locate(env, pool->qpi_site[qtype],
+                                        &qti->qti_id);
+                       if (IS_ERR(lqe))
+                               RETURN(PTR_ERR(lqe));
+                       pool->qpi_grace_lqe[qtype] = lqe;
 #ifdef LPROCFS
                        /* add procfs file to dump the global index, mostly for
                         * debugging purpose */
@@ -633,10 +673,18 @@ struct lquota_entry *qmt_pool_lqe_lookup(const struct lu_env *env,
        if (IS_ERR(pool))
                RETURN((void *)pool);
 
+       if (qid->qid_uid == 0) {
+               /* caller wants to access grace time, no need to look up the
+                * entry since we keep a reference on ID 0 all the time */
+               lqe = pool->qpi_grace_lqe[qtype];
+               lqe_getref(lqe);
+               GOTO(out, lqe);
+       }
+
        /* now that we have the pool, let's look-up the quota entry in the
         * right quota site */
        lqe = lqe_locate(env, pool->qpi_site[qtype], qid);
-
+out:
        qpi_putref(env, pool);
        RETURN(lqe);
 }