From fb855d0a03b5702ab38942fc1b1e41b28420acfd Mon Sep 17 00:00:00 2001 From: Niu Yawei Date: Thu, 3 Jul 2014 23:51:10 -0400 Subject: [PATCH] LU-4249 quota: race in qsd_upd_thread() qsd_upd_thread() uses list_for_each_entry_safe() to process list items one by one, however, it has to drop lock while processing each item, that'll race with other list processing thread. The proper way is to check list head each time when it acquired lock. Signed-off-by: Niu Yawei Change-Id: I55dfe3f65cc214c5d0fd8a9afdda795af94bbdce Reviewed-on: http://review.whamcloud.com/10988 Reviewed-by: Fan Yong Tested-by: Jenkins Reviewed-by: Bobi Jam Reviewed-by: Johann Lombardi Tested-by: Maloo --- lustre/quota/qsd_writeback.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lustre/quota/qsd_writeback.c b/lustre/quota/qsd_writeback.c index 17dfb55..56dbdcb 100644 --- a/lustre/quota/qsd_writeback.c +++ b/lustre/quota/qsd_writeback.c @@ -417,7 +417,7 @@ static int qsd_upd_thread(void *arg) struct lu_env *env; int qtype, rc = 0; bool uptodate; - struct lquota_entry *lqe, *tmp; + struct lquota_entry *lqe; __u64 cur_time; ENTRY; @@ -450,8 +450,9 @@ static int qsd_upd_thread(void *arg) spin_lock(&qsd->qsd_adjust_lock); cur_time = cfs_time_current_64(); - list_for_each_entry_safe(lqe, tmp, &qsd->qsd_adjust_list, - lqe_link) { + while (!list_empty(&qsd->qsd_adjust_list)) { + lqe = list_entry(qsd->qsd_adjust_list.next, + struct lquota_entry, lqe_link); /* deferred items are sorted by time */ if (!cfs_time_beforeq_64(lqe->lqe_adjust_time, cur_time)) -- 1.8.3.1