Whamcloud - gitweb
LU-16772 quota: protect lqe_glbl_data in qmt_site_recalc_cb
authorSergey Cheremencev <scherementsev@ddn.com>
Tue, 25 Apr 2023 18:10:21 +0000 (22:10 +0400)
committerAndreas Dilger <adilger@whamcloud.com>
Thu, 11 May 2023 00:43:48 +0000 (00:43 +0000)
lqe_glbl_data should be protected with lqe_glbl_data_lock in
qmt_site_reaclc_sb like it did in other places. Otherwise it
may cause following panic:

  BUG: unable to handle kernel NULL pointer at 00000000000000f8
  qmt_site_recalc_cb+0x2f8/0x790 [lquota]
  cfs_hash_for_each_tight+0x121/0x310 [libcfs]
  qmt_pool_recalc+0x372/0x9f0 [lquota]

Also protect lqe_glbl_data access with lqe_glbl_data_lock in
qmt_lvbo_free().  Add debugging to see how often this is hit.

Lustre-change: https://review.whamcloud.com/50748
Lustre-commit: TBD (from e3511c6dbfb097308f48957e2e2df8c25f87030a)

Fixes: 1dbcbd70f8 ("LU-15021 quota: protect lqe_glbl_data in lqe")
Signed-off-by: Sergey Cheremencev <scherementsev@ddn.com>
Change-Id: I030f14b02062151f1708a03ac7414a9991f798f6
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/50784
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Hongchao Zhang <hongchao@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/quota/qmt_entry.c
lustre/quota/qmt_lock.c
lustre/quota/qmt_pool.c

index d35d05a..7a3905f 100644 (file)
@@ -1098,6 +1098,9 @@ struct lqe_glbl_data *qmt_alloc_lqe_gd(struct qmt_pool_info *pool, int qtype)
 
 void qmt_free_lqe_gd(struct lqe_glbl_data *lgd)
 {
+       if (unlikely(!lgd))
+               return;
+
        OBD_FREE(lgd->lqeg_arr,
                 sizeof(struct lqe_glbl_entry) * lgd->lqeg_num_alloc);
        OBD_FREE(lgd, sizeof(struct lqe_glbl_data));
index 523abae..a21d466 100644 (file)
@@ -518,12 +518,22 @@ int qmt_lvbo_free(struct lu_device *ld, struct ldlm_resource *res)
 
        if (res->lr_name.name[LUSTRE_RES_ID_QUOTA_SEQ_OFF] != 0) {
                struct lquota_entry *lqe = res->lr_lvb_data;
-               struct lqe_glbl_data *lgd = lqe->lqe_glbl_data;
+               struct lqe_glbl_data *lgd;
 
                mutex_lock(&lqe->lqe_glbl_data_lock);
+               lgd = lqe->lqe_glbl_data;
                lqe->lqe_glbl_data = NULL;
-               qmt_free_lqe_gd(lgd);
                mutex_unlock(&lqe->lqe_glbl_data_lock);
+               qmt_free_lqe_gd(lgd);
+               if (unlikely(lgd == NULL)) {
+                       struct lu_fid fid;
+                       union lquota_id qid;
+
+                       fid_extract_from_quota_res(&fid, &qid, &res->lr_name);
+                       CWARN("%s: lvbo of "DFID" (id=%llx) not fully init \n",
+                             lu2qmt_dev(ld)->qmt_svname, PFID(&fid),
+                             qid.qid_uid);
+               }
 
                /* release lqe reference */
                lqe_putref(lqe);
index 33c44e1..fc525a1 100644 (file)
@@ -1100,10 +1100,14 @@ static int qmt_site_recalc_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
                        /* Find all lqes with lqe_id to reseed lgd array */
                        rc = qmt_pool_lqes_lookup_spec(env, qmt, lqe_rtype(lqe),
                                                lqe_qtype(lqe), &lqe->lqe_id);
-                       if (!rc && qti_lqes_glbl(env)->lqe_glbl_data) {
-                               qmt_seed_glbe(env,
-                                       qti_lqes_glbl(env)->lqe_glbl_data);
-                               qmt_id_lock_notify(qmt, qti_lqes_glbl(env));
+                       if (!rc) {
+                               struct lquota_entry *lqeg = qti_lqes_glbl(env);
+
+                               mutex_lock(&lqeg->lqe_glbl_data_lock);
+                               if (lqeg->lqe_glbl_data)
+                                       qmt_seed_glbe(env, lqeg->lqe_glbl_data);
+                               mutex_unlock(&lqeg->lqe_glbl_data_lock);
+                               qmt_id_lock_notify(qmt, lqeg);
                        }
                        qti_lqes_fini(env);
                }