+static inline
+void qmt_grant_lqes(const struct lu_env *env, __u64 *slv, __u64 cnt)
+{
+ int i;
+
+ for (i = 0; i < qti_lqes_cnt(env); i++)
+ qti_lqe_granted(env, i) += cnt;
+
+ *slv += cnt;
+}
+
+static inline bool qmt_lqes_can_rel(const struct lu_env *env, __u64 cnt)
+{
+ bool can_release = true;
+ int i;
+
+ for (i = 0; i < qti_lqes_cnt(env); i++) {
+ if (cnt > qti_lqe_granted(env, i)) {
+ LQUOTA_ERROR(qti_lqes(env)[i],
+ "Can't release %llu that is larger than lqe_granted.\n",
+ cnt);
+ can_release = false;
+ }
+ }
+ return can_release;
+}
+
+static inline void qmt_rel_lqes(const struct lu_env *env, __u64 *slv, __u64 cnt)
+{
+ int i;
+
+ for (i = 0; i < qti_lqes_cnt(env); i++)
+ qti_lqe_granted(env, i) -= cnt;
+
+ *slv -= cnt;
+}
+
+static inline bool qmt_lqes_cannot_grant(const struct lu_env *env, __u64 cnt)
+{
+ bool cannot_grant = false;
+ int i;
+
+ for (i = 0; i < qti_lqes_cnt(env); i++) {
+ if (qti_lqe_hard(env, i) != 0 &&
+ qti_lqe_granted(env, i) + cnt > qti_lqe_hard(env, i)) {
+ cannot_grant = true;
+ break;
+ }
+ }
+ return cannot_grant;
+}
+
+static inline __u64 qmt_lqes_grant_some_quota(const struct lu_env *env)
+{
+ __u64 min_count, tmp;
+ bool flag = false;
+ int i;
+
+ for (i = 0, min_count = 0; i < qti_lqes_cnt(env); i++) {
+ if (!qti_lqes(env)[i]->lqe_enforced &&
+ !qti_lqes(env)[i]->lqe_is_global)
+ continue;
+
+ tmp = qti_lqe_hard(env, i) - qti_lqe_granted(env, i);
+ if (flag) {
+ min_count = tmp < min_count ? tmp : min_count;
+ } else {
+ flag = true;
+ min_count = tmp;
+ }
+ }
+ return min_count;
+}
+
+static inline __u64 qmt_lqes_alloc_expand(const struct lu_env *env,
+ __u64 slv_granted, __u64 spare)
+{
+ __u64 min_count, tmp;
+ bool flag = false;
+ int i;
+
+ for (i = 0, min_count = 0; i < qti_lqes_cnt(env); i++) {
+ /* Don't take into account not enforced lqes that belong
+ * to non global pool. These lqes present in array to
+ * support actual lqe_granted even for lqes without limits. */
+ if (!qti_lqes(env)[i]->lqe_enforced &&
+ !qti_lqes(env)[i]->lqe_is_global)
+ continue;
+
+ tmp = qmt_alloc_expand(qti_lqes(env)[i], slv_granted, spare);
+ if (flag) {
+ min_count = tmp < min_count ? tmp : min_count;
+ } else {
+ flag = true;
+ min_count = tmp;
+ }
+ }
+ return min_count;
+}
+
+static inline void qmt_lqes_tune_grace(const struct lu_env *env, __u64 now)
+{
+ int i;
+
+ for (i = 0; i < qti_lqes_cnt(env); i++) {
+ struct lquota_entry *lqe;
+
+ lqe = qti_lqes(env)[i];
+ if (lqe->lqe_softlimit != 0) {
+ if (lqe->lqe_granted > lqe->lqe_softlimit &&
+ lqe->lqe_gracetime == 0) {
+ /* First time over soft limit, let's start grace
+ * timer */
+ lqe->lqe_gracetime = now + qmt_lqe_grace(lqe);
+ } else if (lqe->lqe_granted <= lqe->lqe_softlimit &&
+ lqe->lqe_gracetime != 0) {
+ /* Clear grace timer */
+ lqe->lqe_gracetime = 0;
+ }
+ }
+ }
+}
+