diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index c26765080f28..61549bd95b32 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -463,6 +463,7 @@ struct gfs2_quota_data { u64 qd_sync_gen; unsigned long qd_last_warn; struct rcu_head qd_rcu; + unsigned int ref_cnt; }; enum { diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 1ed17226d9ed..9f3a876283f5 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -480,6 +480,7 @@ static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp) } } + qd->ref_cnt++; *qdp = qd; return 0; @@ -493,6 +494,7 @@ static void qd_unlock(struct gfs2_quota_data *qd) bh_put(qd); slot_put(qd); qd_put(qd); + qd->ref_cnt--; } static int qdsb_get(struct gfs2_sbd *sdp, struct kqid qid, @@ -1422,6 +1424,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) qd->qd_change = qc_change; qd->qd_slot = slot; qd->qd_slot_count = 1; + qd->ref_cnt = 0; spin_lock(&qd_lock); BUG_ON(test_and_set_bit(slot, sdp->sd_quota_bitmap)); @@ -1457,8 +1460,9 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp) struct gfs2_quota_data *qd; spin_lock(&qd_lock); - while (!list_empty(head)) { - qd = list_last_entry(head, struct gfs2_quota_data, qd_list); + list_for_each_entry_safe(qd, safe, head, qd_list) { + if (qd->ref_cnt) + continue; list_del(&qd->qd_list);