Whamcloud - gitweb
LU-12853 ptlrpc: zero session enviroment
[fs/lustre-release.git] / lustre / quota / qmt_internal.h
index d83ff83..a3ab56f 100644 (file)
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2017, Intel Corporation.
  * Use is subject to license terms.
  */
 
-#include "lquota_internal.h"
-
 #ifndef _QMT_INTERNAL_H
 #define _QMT_INTERNAL_H
 
+#include "lquota_internal.h"
+
 /*
  * The Quota Master Target Device.
  * The qmt is responsible for:
@@ -65,19 +65,21 @@ struct qmt_device {
         * Once we support quota on non-default pools, then more pools will
         * be added to this hash table and pool master setup would have to be
         * handled via configuration logs */
-       cfs_hash_t              *qmt_pool_hash;
+       struct cfs_hash         *qmt_pool_hash;
 
        /* List of pools managed by this master target */
-       cfs_list_t               qmt_pool_list;
+       struct list_head         qmt_pool_list;
+       /* rw spinlock to protect pool list */
+       rwlock_t                 qmt_pool_lock;
 
        /* procfs root directory for this qmt */
-       cfs_proc_dir_entry_t    *qmt_proc;
+       struct proc_dir_entry   *qmt_proc;
 
        /* dedicated thread in charge of space rebalancing */
        struct ptlrpc_thread     qmt_reba_thread;
 
        /* list of lqe entry which need space rebalancing */
-       cfs_list_t               qmt_reba_list;
+       struct list_head         qmt_reba_list;
 
        /* lock protecting rebalancing list */
        spinlock_t               qmt_reba_lock;
@@ -86,29 +88,24 @@ struct qmt_device {
 
 };
 
+#define QPI_MAXNAME    (LOV_MAXPOOLNAME + 1)
+
 /*
  * Per-pool quota information.
  * The qmt creates one such structure for each pool
- * with quota enforced. All the structures are kept in a hash which is used to
- * determine whether or not quota is enforced for a given pool.
- * We currently only support the default data pool and default metadata pool
- * with the pool_id 0.
+ * with quota enforced. All the structures are kept in a list.
+ * We currently only support the default data pool and default metadata pool.
  */
 struct qmt_pool_info {
-       /* link to qmt's pool hash */
-       cfs_hlist_node_t         qpi_hash;
-
        /* chained list of all pools managed by the same qmt */
-       cfs_list_t               qpi_linkage;
+       struct list_head         qpi_linkage;
 
-       /* Pool key composed of pool_id | (pool_type << 16)
-        * Only pool ID 0 is supported for now and the pool type is either
-        * QUOTA_RES_MD or QUOTA_RES_DT.
-        * immutable after creation. */
-       __u32                    qpi_key;
+       /* Could be  LQUOTA_RES_MD or LQUOTA_RES_DT */
+       int                      qpi_rtype;
+       char                     qpi_name[QPI_MAXNAME];
 
        /* track users of this pool instance */
-       cfs_atomic_t             qpi_ref;
+       atomic_t                 qpi_ref;
 
        /* back pointer to master target
         * immutable after creation. */
@@ -116,21 +113,21 @@ struct qmt_pool_info {
 
        /* pointer to dt object associated with global indexes for both user
         * and group quota */
-       struct dt_object        *qpi_glb_obj[MAXQUOTAS];
+       struct dt_object        *qpi_glb_obj[LL_MAXQUOTAS];
 
        /* A pool supports two different quota types: user and group quota.
         * Each quota type has its own global index and lquota_entry hash table.
         */
-       struct lquota_site      *qpi_site[MAXQUOTAS];
+       struct lquota_site      *qpi_site[LL_MAXQUOTAS];
 
        /* number of slaves registered for each quota types */
-       int                      qpi_slv_nr[MAXQUOTAS];
+       int                      qpi_slv_nr[LL_MAXQUOTAS];
 
        /* reference on lqe (ID 0) storing grace time. */
-       struct lquota_entry     *qpi_grace_lqe[MAXQUOTAS];
+       struct lquota_entry     *qpi_grace_lqe[LL_MAXQUOTAS];
 
        /* procfs root directory for this pool */
-       cfs_proc_dir_entry_t    *qpi_proc;
+       struct proc_dir_entry   *qpi_proc;
 
        /* pool directory where all indexes related to this pool instance are
         * stored */
@@ -139,6 +136,22 @@ struct qmt_pool_info {
        /* Global quota parameters which apply to all quota type */
        /* the least value of qunit */
        unsigned long            qpi_least_qunit;
+
+       /* Least value of qunit when soft limit is exceeded.
+        *
+        * When soft limit is exceeded, qunit will be shrinked to least_qunit
+        * (1M for block limit), that results in significant write performance
+        * drop since the client will turn to sync write from now on.
+        *
+        * To retain the write performance in an acceptable level, we choose
+        * to sacrifice grace time accuracy a bit and use a larger least_qunit
+        * when soft limit is exceeded. It's (qpi_least_qunit * 4) by default,
+        * and user may enlarge it via procfs to get even better performance
+        * (with the cost of losing more grace time accuracy).
+        *
+        * See qmt_calc_softlimit().
+        */
+       unsigned long            qpi_soft_least_qunit;
 };
 
 /*
@@ -189,15 +202,7 @@ extern struct lu_context_key qmt_thread_key;
 static inline
 struct qmt_thread_info *qmt_info(const struct lu_env *env)
 {
-       struct qmt_thread_info  *info;
-
-       info = lu_context_key_get(&env->le_ctx, &qmt_thread_key);
-       if (info == NULL) {
-               lu_env_refill((struct lu_env *)env);
-               info = lu_context_key_get(&env->le_ctx, &qmt_thread_key);
-       }
-       LASSERT(info);
-       return info;
+       return lu_env_info(env, &qmt_thread_key);
 }
 
 /* helper routine to convert a lu_device into a qmt_device */
@@ -248,21 +253,40 @@ static inline void qmt_restore(struct lquota_entry *lqe,
                (slv) -= (cnt);              \
        } while (0)
 
-/* helper routine returning true when the id has run out of quota space, which
- * means that it has either:
- * - reached hardlimit
- * OR
- * - reached softlimit and grace time expired already */
-static inline bool qmt_space_exhausted(struct lquota_entry *lqe, __u64 now)
+/* helper routine returning true when reached hardlimit */
+static inline bool qmt_hard_exhausted(struct lquota_entry *lqe)
 {
        if (lqe->lqe_hardlimit != 0 && lqe->lqe_granted >= lqe->lqe_hardlimit)
                return true;
+       return false;
+}
+
+/* helper routine returning true when reached softlimit */
+static inline bool qmt_soft_exhausted(struct lquota_entry *lqe, __u64 now)
+{
        if (lqe->lqe_softlimit != 0 && lqe->lqe_granted > lqe->lqe_softlimit &&
            lqe->lqe_gracetime != 0 && now >= lqe->lqe_gracetime)
                return true;
        return false;
 }
 
+/* helper routine returning true when the id has run out of quota space:
+ * - reached hardlimit
+ * OR
+ * - reached softlimit and grace time expired already */
+static inline bool qmt_space_exhausted(struct lquota_entry *lqe, __u64 now)
+{
+       return (qmt_hard_exhausted(lqe) || qmt_soft_exhausted(lqe, now));
+}
+
+/* helper routine clearing the default quota setting  */
+static inline void qmt_lqe_clear_default(struct lquota_entry *lqe)
+{
+       lqe->lqe_is_default = false;
+       lqe->lqe_gracetime &= ~((__u64)LQUOTA_FLAG_DEFAULT <<
+                                                       LQUOTA_GRACE_BITS);
+}
+
 /* number of seconds to wait for slaves to release quota space after
  * rebalancing */
 #define QMT_REBA_TIMEOUT 2
@@ -276,10 +300,12 @@ int qmt_pool_new_conn(const struct lu_env *, struct qmt_device *,
                      struct lu_fid *, struct lu_fid *, __u64 *,
                      struct obd_uuid *);
 struct lquota_entry *qmt_pool_lqe_lookup(const struct lu_env *,
-                                        struct qmt_device *, int, int, int,
+                                        struct qmt_device *, int, int,
                                         union lquota_id *);
 /* qmt_entry.c */
 extern struct lquota_entry_operations qmt_lqe_ops;
+int qmt_lqe_set_default(const struct lu_env *env, struct qmt_pool_info *pool,
+                       struct lquota_entry *lqe, bool create_record);
 struct thandle *qmt_trans_start_with_slv(const struct lu_env *,
                                         struct lquota_entry *,
                                         struct dt_object *,
@@ -300,6 +326,9 @@ void qmt_revalidate(const struct lu_env *, struct lquota_entry *);
 __u64 qmt_alloc_expand(struct lquota_entry *, __u64, __u64);
 
 /* qmt_handler.c */
+int qmt_set_with_lqe(const struct lu_env *env, struct qmt_device *qmt,
+                    struct lquota_entry *lqe, __u64 hard, __u64 soft,
+                    __u64 time, __u32 valid, bool is_default, bool is_updated);
 int qmt_dqacq0(const struct lu_env *, struct lquota_entry *,
               struct qmt_device *, struct obd_uuid *, __u32, __u64, __u64,
               struct quota_body *);