Whamcloud - gitweb
LU-4249 quota: race in qsd_upd_thread() 88/10988/2
authorNiu Yawei <yawei.niu@intel.com>
Fri, 4 Jul 2014 03:51:10 +0000 (23:51 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 8 Jul 2014 15:42:12 +0000 (15:42 +0000)
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 <yawei.niu@intel.com>
Change-Id: I55dfe3f65cc214c5d0fd8a9afdda795af94bbdce
Reviewed-on: http://review.whamcloud.com/10988
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Jenkins
Reviewed-by: Bobi Jam <bobijam@gmail.com>
Reviewed-by: Johann Lombardi <johann.lombardi@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
lustre/quota/qsd_writeback.c

index 17dfb55..56dbdcb 100644 (file)
@@ -417,7 +417,7 @@ static int qsd_upd_thread(void *arg)
        struct lu_env           *env;
        int                      qtype, rc = 0;
        bool                     uptodate;
        struct lu_env           *env;
        int                      qtype, rc = 0;
        bool                     uptodate;
-       struct lquota_entry     *lqe, *tmp;
+       struct lquota_entry     *lqe;
        __u64                    cur_time;
        ENTRY;
 
        __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();
 
                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))
                        /* deferred items are sorted by time */
                        if (!cfs_time_beforeq_64(lqe->lqe_adjust_time,
                                                 cur_time))