Whamcloud - gitweb
LU-15880 quota: fix issues in reserving quota
[fs/lustre-release.git] / lustre / quota / qsd_handler.c
index 1c8e43a..0c34e6c 100644 (file)
@@ -1064,8 +1064,16 @@ static void qsd_op_end0(const struct lu_env *env, struct qsd_qtype_info *qqi,
                qsd_refresh_usage(env, lqe);
 
        lqe_write_lock(lqe);
-       if (qid->lqi_space > 0)
-               lqe->lqe_pending_write -= qid->lqi_space;
+       if (qid->lqi_space > 0) {
+               if (lqe->lqe_pending_write < qid->lqi_space) {
+                       LQUOTA_ERROR(lqe,
+                                    "More pending write quota to reduce (pending %llu, space %lld)\n",
+                                    lqe->lqe_pending_write, qid->lqi_space);
+                       lqe->lqe_pending_write = 0;
+               } else {
+                       lqe->lqe_pending_write -= qid->lqi_space;
+               }
+       }
        if (env != NULL)
                adjust = qsd_adjust_needed(lqe);
        else
@@ -1290,10 +1298,9 @@ int qsd_reserve_or_free_quota(const struct lu_env *env,
                              struct qsd_instance *qsd,
                              struct lquota_id_info *qi)
 {
-       struct lquota_entry *lqe;
        struct qsd_qtype_info  *qqi;
-       int rc = 0;
        bool is_free = qi->lqi_space < 0;
+       int rc = 0;
 
        ENTRY;
 
@@ -1327,31 +1334,21 @@ int qsd_reserve_or_free_quota(const struct lu_env *env,
         * or - the user/group is root
         * or - quota accounting isn't enabled
         */
-       if (!qsd_type_enabled(qsd, qi->lqi_type) || qi->lqi_id.qid_uid == 0 ||
-           (qsd->qsd_type_array[qi->lqi_type])->qqi_acct_failed)
+       if (!is_free &&
+           (!qsd_type_enabled(qsd, qi->lqi_type) || qi->lqi_id.qid_uid == 0 ||
+             (qsd->qsd_type_array[qi->lqi_type])->qqi_acct_failed))
                RETURN(0);
 
        if (is_free) {
-               /* look up lquota entry associated with qid */
-               lqe = lqe_locate(env, qqi->qqi_site, &qi->lqi_id);
-               if (IS_ERR(lqe))
-                       RETURN(PTR_ERR(lqe));
-               if (!lqe->lqe_enforced) {
-                       lqe_putref(lqe);
-                       RETURN(0);
-               }
-
-               qi->lqi_qentry = lqe;
-
-               /* lqe will be put in qsd_op_end0 */
                qsd_op_end0(env, qsd->qsd_type_array[qi->lqi_type], qi);
-               qi->lqi_qentry = NULL;
        } else {
-               /* manage quota enforcement for this ID */
-               rc = qsd_op_begin0(env, qsd->qsd_type_array[qi->lqi_type], qi,
-                                  qi->lqi_space, NULL);
+               long long qspace = qi->lqi_space;
 
-               if (qi->lqi_qentry != NULL) {
+               /* the acquired quota will add to lqi_space in qsd_op_begin0 */
+               qi->lqi_space = 0;
+               rc = qsd_op_begin0(env, qsd->qsd_type_array[qi->lqi_type], qi,
+                                  qspace, NULL);
+               if (rc && qi->lqi_qentry) {
                        lqe_putref(qi->lqi_qentry);
                        qi->lqi_qentry = NULL;
                }