From 4597a2b4fc33711f66eb1c21fc125d028bd3f2ec Mon Sep 17 00:00:00 2001 From: Yang Sheng Date: Sun, 26 Apr 2020 19:56:40 +0800 Subject: [PATCH] LU-13054 ldiskfs: htree_node wrongly granted The thread was waken up accidently. So need check whether the lock granted or not after wake up. Also fix issue that major always set to 0 since hbit initialize incorrect. The performace should be impacted especial operate in big directory. kernel BUG at lustre/ldiskfs/htree_lock.c:429! Call Trace: htree_node_release_all+0x5a/0x80 [ldiskfs] htree_unlock+0x22/0x70 [ldiskfs] osd_index_ea_delete+0x30e/0xb10 [osd_ldiskfs] lod_sub_delete+0x1c8/0x460 [lod] lod_delete+0x24/0x30 [lod] __mdd_index_delete_only+0x194/0x250 [mdd] __mdd_index_delete+0x46/0x290 [mdd] mdd_unlink+0x5f8/0xaa0 [mdd] mdo_unlink+0x46/0x48 [mdt] mdt_reint_unlink+0xbed/0x14b0 [mdt] Signed-off-by: Yang Sheng Change-Id: I5972961bc78b349214c6756642717d126f0c4b26 Reviewed-on: https://review.whamcloud.com/38371 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Jian Yu Reviewed-by: Oleg Drokin --- .../kernel_patches/patches/rhel7.7/ext4-pdirop.patch | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ldiskfs/kernel_patches/patches/rhel7.7/ext4-pdirop.patch b/ldiskfs/kernel_patches/patches/rhel7.7/ext4-pdirop.patch index 422d7e7..0ae29c9 100644 --- a/ldiskfs/kernel_patches/patches/rhel7.7/ext4-pdirop.patch +++ b/ldiskfs/kernel_patches/patches/rhel7.7/ext4-pdirop.patch @@ -210,7 +210,7 @@ Index: linux-3.10.0-229.1.2.fc21.x86_64/fs/ext4/htree_lock.c =================================================================== --- /dev/null +++ linux-3.10.0-229.1.2.fc21.x86_64/fs/ext4/htree_lock.c -@@ -0,0 +1,891 @@ +@@ -0,0 +1,895 @@ +/* + * fs/ext4/htree_lock.c + * @@ -436,22 +436,25 @@ Index: linux-3.10.0-229.1.2.fc21.x86_64/fs/ext4/htree_lock.c + } + + newlk->lk_task = current; -+ set_current_state(TASK_UNINTERRUPTIBLE); + /* conflict, attach it on blocked list of curlk */ + list_add_tail(&newln->ln_blocked_list, &curln->ln_blocked_list); + list_add(&newln->ln_alive_list, &curln->ln_alive_list); + ln_block_inc(dep, newln->ln_mode); + ++retry: ++ set_current_state(TASK_UNINTERRUPTIBLE); + htree_spin_unlock(newlk->lk_head, dep); + /* wait to be given the lock */ + if (newlk->lk_task != NULL) + schedule(); + /* granted, no doubt, wake up will set me RUNNING */ -+ if (event == NULL || htree_key_event_ignore(child, newln)) -+ return 0; /* granted without lh_lock */ -+ + htree_spin_lock(newlk->lk_head, dep); -+ htree_key_event_enqueue(child, newln, dep, event); ++ /* Need to check lock really granted, thread maybe awaken wrongly */ ++ if (list_empty(&newln->ln_granted_list) && htree_key_list_empty(newln)) ++ goto retry; ++ if (event && !htree_key_event_ignore(child, newln)) ++ htree_key_event_enqueue(child, newln, dep, event); ++ + return 1; /* still hold lh_lock */ +} + @@ -1012,10 +1015,11 @@ Index: linux-3.10.0-229.1.2.fc21.x86_64/fs/ext4/htree_lock.c + return NULL; + + if (hbits < HTREE_HBITS_MIN) -+ lhead->lh_hbits = HTREE_HBITS_MIN; ++ hbits = HTREE_HBITS_MIN; + else if (hbits > HTREE_HBITS_MAX) -+ lhead->lh_hbits = HTREE_HBITS_MAX; ++ hbits = HTREE_HBITS_MAX; + ++ lhead->lh_hbits = hbits; + lhead->lh_lock = 0; + lhead->lh_depth = depth; + INIT_LIST_HEAD(&lhead->lh_blocked_list); -- 1.8.3.1