Skip to content

Commit a475c5d

Browse files
author
Andreas Gruenbacher
committed
gfs2: Free quota data objects synchronously
In gfs2_quota_cleanup(), wait for the quota data objects to be freed before returning. Otherwise, there is no guarantee that the quota data objects will be gone when their kmem cache is destroyed. Signed-off-by: Andreas Gruenbacher <[email protected]>
1 parent bb73ae8 commit a475c5d

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

fs/gfs2/quota.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,11 @@ static inline void spin_unlock_bucket(unsigned int hash)
109109
static void gfs2_qd_dealloc(struct rcu_head *rcu)
110110
{
111111
struct gfs2_quota_data *qd = container_of(rcu, struct gfs2_quota_data, qd_rcu);
112+
struct gfs2_sbd *sdp = qd->qd_sbd;
113+
112114
kmem_cache_free(gfs2_quotad_cachep, qd);
115+
if (atomic_dec_and_test(&sdp->sd_quota_count))
116+
wake_up(&sdp->sd_kill_wait);
113117
}
114118

115119
static void gfs2_qd_dispose(struct gfs2_quota_data *qd)
@@ -143,7 +147,6 @@ static void gfs2_qd_list_dispose(struct list_head *list)
143147
list_del(&qd->qd_lru);
144148

145149
gfs2_qd_dispose(qd);
146-
atomic_dec(&sdp->sd_quota_count);
147150
}
148151
}
149152

@@ -317,13 +320,24 @@ static void qd_hold(struct gfs2_quota_data *qd)
317320

318321
static void qd_put(struct gfs2_quota_data *qd)
319322
{
323+
struct gfs2_sbd *sdp;
324+
320325
if (lockref_put_or_lock(&qd->qd_lockref))
321326
return;
322327

328+
BUG_ON(__lockref_is_dead(&qd->qd_lockref));
329+
sdp = qd->qd_sbd;
330+
if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))) {
331+
lockref_mark_dead(&qd->qd_lockref);
332+
spin_unlock(&qd->qd_lockref.lock);
333+
334+
gfs2_qd_dispose(qd);
335+
return;
336+
}
337+
323338
qd->qd_lockref.count = 0;
324339
list_lru_add(&gfs2_qd_lru, &qd->qd_lru);
325340
spin_unlock(&qd->qd_lockref.lock);
326-
327341
}
328342

329343
static int slot_get(struct gfs2_quota_data *qd)
@@ -1465,16 +1479,33 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp)
14651479
{
14661480
struct gfs2_quota_data *qd;
14671481
LIST_HEAD(dispose);
1482+
int count;
1483+
1484+
BUG_ON(test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags));
14681485

14691486
spin_lock(&qd_lock);
14701487
list_for_each_entry(qd, &sdp->sd_quota_list, qd_list) {
1488+
spin_lock(&qd->qd_lockref.lock);
1489+
if (qd->qd_lockref.count != 0) {
1490+
spin_unlock(&qd->qd_lockref.lock);
1491+
continue;
1492+
}
1493+
lockref_mark_dead(&qd->qd_lockref);
1494+
spin_unlock(&qd->qd_lockref.lock);
1495+
14711496
list_lru_del(&gfs2_qd_lru, &qd->qd_lru);
14721497
list_add(&qd->qd_lru, &dispose);
14731498
}
14741499
spin_unlock(&qd_lock);
14751500

14761501
gfs2_qd_list_dispose(&dispose);
1477-
gfs2_assert_warn(sdp, !atomic_read(&sdp->sd_quota_count));
1502+
1503+
wait_event_timeout(sdp->sd_kill_wait,
1504+
(count = atomic_read(&sdp->sd_quota_count)) == 0,
1505+
HZ * 60);
1506+
1507+
if (count != 0)
1508+
fs_err(sdp, "%d left-over quota data objects\n", count);
14781509

14791510
kvfree(sdp->sd_quota_bitmap);
14801511
sdp->sd_quota_bitmap = NULL;

0 commit comments

Comments
 (0)