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>
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));
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);
/* 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);
}