Whamcloud - gitweb
LU-18780 llite: fix the hung during get all quota 28/58328/5
authorHongchao Zhang <hongchao@whamcloud.com>
Wed, 7 May 2025 12:17:02 +0000 (20:17 +0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 21 May 2025 05:17:00 +0000 (05:17 +0000)
If "lfs quota -a" is called simultaneously, the different list for
each call in ll_sb_info->ll_all_quota_list could be out of order,
then it could be stuck in "quotactl_getallquota".

Signed-off-by: Hongchao Zhang <hongchao@whamcloud.com>
Change-Id: I28099a24127a95ad0db301ee65707962efa67fe8
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/58328
Reviewed-by: Sergey Cheremencev <scherementsev@ddn.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/llite/dir.c

index 09346e3..01c73a4 100644 (file)
@@ -1620,20 +1620,21 @@ static int quotactl_getallquota(struct ll_sb_info *sbi,
        struct if_quotactl_iter *iter = NULL;
        void __user *buffer = (void __user *)qctl->qc_allquota_buffer;
        __u64 cur = 0, count = qctl->qc_allquota_buflen;
+       bool found = false;
        int rc = 0;
 
        ENTRY;
 
        mutex_lock(&quotactl_iter_lock);
 
-       while ((ll_iter = list_first_entry_or_null(&sbi->ll_all_quota_list,
-                                               struct ll_quotactl_iter_list,
-                                               lqil_sbi_list)) != NULL) {
-               if (qctl->qc_allquota_mark == ll_iter->lqil_mark)
+       list_for_each_entry(ll_iter, &sbi->ll_all_quota_list, lqil_sbi_list) {
+               if (qctl->qc_allquota_mark == ll_iter->lqil_mark) {
+                       found = true;
                        break;
+               }
        }
 
-       if (!ll_iter) {
+       if (!found) {
                mutex_unlock(&quotactl_iter_lock);
                RETURN(-EBUSY);
        }
@@ -1666,6 +1667,9 @@ static int quotactl_getallquota(struct ll_sb_info *sbi,
                OBD_SLAB_FREE_PTR(iter, quota_iter_slab);
        }
 
+       list_del_init(&ll_iter->lqil_sbi_list);
+       OBD_FREE_PTR(ll_iter);
+
        mutex_unlock(&quotactl_iter_lock);
 
        RETURN(rc);