- /* release quota space */
- rc = qmt_dqacq0(env, lqe, qmt, &exp->exp_client_uuid,
- QUOTA_DQACQ_FL_REL, lvb->lvb_id_rel, 0, &qti->qti_body);
- if (rc || qti->qti_body.qb_count != lvb->lvb_id_rel)
- LQUOTA_ERROR(lqe, "failed to release quota space on glimpse "
- "%llu!=%llu : rc = %d\n", qti->qti_body.qb_count,
- lvb->lvb_id_rel, rc);
- class_export_put(exp);
+ stype = qmt_uuid2idx(&exp->exp_client_uuid, &idx);
+ if (stype < 0)
+ GOTO(out_exp, rc = stype);
+
+ need_revoke = qmt_clear_lgeg_arr_nu(lqe, stype, idx);
+ if (lvb->lvb_id_rel == 0) {
+ /* nothing to release */
+ if (lvb->lvb_id_may_rel != 0)
+ /* but might still release later ... */
+ lqe->lqe_may_rel += lvb->lvb_id_may_rel;
+ }
+
+ if (!need_revoke && lvb->lvb_id_rel == 0)
+ GOTO(out_exp, rc = 0);
+
+ rc = qmt_pool_lqes_lookup(env, qmt, lqe_rtype(lqe), stype,
+ lqe_qtype(lqe), &lqe->lqe_id, NULL, idx);
+ if (rc)
+ GOTO(out_exp, rc);
+
+ if (need_revoke && qmt_set_revoke(env, lqe, stype, idx)) {
+ mutex_lock(&lqe->lqe_glbl_data_lock);
+ if (lqe->lqe_glbl_data) {
+ qmt_seed_glbe_edquot(env, lqe->lqe_glbl_data);
+ qmt_id_lock_notify(qmt, lqe);
+ }
+ mutex_unlock(&lqe->lqe_glbl_data_lock);
+ }
+
+ if (lvb->lvb_id_rel) {
+ LQUOTA_DEBUG(lqe, "releasing:%llu may release:%llu",
+ lvb->lvb_id_rel, lvb->lvb_id_may_rel);
+
+ /* release quota space */
+ rc = qmt_dqacq0(env, qmt, &exp->exp_client_uuid,
+ QUOTA_DQACQ_FL_REL, lvb->lvb_id_rel,
+ 0, &qti->qti_body,
+ qmt_dom(lqe_rtype(lqe), stype) ? -1 : idx);
+ if (rc || qti->qti_body.qb_count != lvb->lvb_id_rel)
+ LQUOTA_ERROR(lqe,
+ "failed to release quota space on glimpse %llu!=%llu : rc = %d\n",
+ qti->qti_body.qb_count,
+ lvb->lvb_id_rel, rc);
+ }
+ qti_lqes_fini(env);