From nobody Thu Apr 9 04:03:26 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5AC5E211A05 for ; Wed, 11 Mar 2026 07:52:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773215559; cv=none; b=DCoQ7RF/V/6aGjZ3VCwIbYsrvOFWPcQWEWT4Tu/BbObhDo4TNR4m3HlYb8+CiQHMBFQqvwWiNf5CmP/ZnvBWgHyCI+yVA3jgFD2y6Fopj+XumWKgDaAL30u2WHOpB9vYpVBxv4EUZmmHDJOesLSmmfcpid5ERalskrrJNnJD8U8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773215559; c=relaxed/simple; bh=gb5EWYjWhjalqlv+0aCnFuFY4MyyW6XdhH8rsxJQCfE=; h=Date:From:To:Subject:Content-Type:MIME-Version:Message-ID; b=ftpb9yLqDEmAE/ABL/+dHamIGZp0f8bNqTXWgGXZlYXswlFE904CbE8o93AYCOp1/9G36mtUu8UvnwnRvT6J2uLVMbCujQJpKmzDBVJm68ukhPp1mxjIwv29CICQ8WhO/vjDTC9xIgv6UT/iGPPIvzSzQwkCUcguffE221ki7+k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=NvVCSfYi; arc=none smtp.client-ip=220.197.31.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="NvVCSfYi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=Date:From:To:Subject:Content-Type:MIME-Version: Message-ID; bh=gb5EWYjWhjalqlv+0aCnFuFY4MyyW6XdhH8rsxJQCfE=; b=N vVCSfYi6LL2CV0Y3/kmJJZOGoOKqzIUJ5I8i18mA+KlcQywV32uxT3xmVN8M+6mf LF6NHkGPtbs30GGBs5islxS6ROGnnknRfkSgTPX6WI8kuFnReqgaSqUkPphCd/4Q 6hf3LR9iJgi8NvmUPfTJgTPWnIljBPGwVP3u1GV2Tw= Received: from luckd0g$163.com ( [183.205.138.18] ) by ajax-webmail-wmsvr-40-127 (Coremail) ; Wed, 11 Mar 2026 15:51:38 +0800 (CST) Date: Wed, 11 Mar 2026 15:51:38 +0800 (CST) From: "Jianzhou Zhao" To: mark@fasheh.com, jlbec@evilplan.org, joseph.qi@linux.alibaba.com, ocfs2-devel@lists.linux.dev, linux-kernel@vger.kernel.org Subject: possible deadlock in ocfs2_wipe_inode X-Priority: 3 X-Mailer: Coremail Webmail Server Version 2023.4-cmXT build 20251222(83accb85) Copyright (c) 2002-2026 www.mailtech.cn 163com X-NTES-SC: AL_Qu2cAf6aukwi7imaZ+kfmU4Rhug7UMO3uf8n24JfPJ9wjA/p2yseUUF9NmPf88CwFTuXvxiGfTNO1/ZAU5Bifrwx9tURzJMRXSpwxeJsKK6NHQ== Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <3d199d9e.68fb.19cdbe142b2.Coremail.luckd0g@163.com> X-Coremail-Locale: zh_CN X-CM-TRANSID: fygvCgD319ELH7FpKr52AA--.38837W X-CM-SenderInfo: poxfyvkqj6il2tof0z/xtbC9gqQG2mxHwq5+gAA35 X-Coremail-Antispam: 1U5529EdanIXcx71UUUUU7vcSsGvfC2KfnxnUU== Content-Type: text/plain; charset="utf-8" Subject: [BUG] ocfs2: WARNING: possible circular locking dependency in ocfs= 2_evict_inode Dear Maintainers, We are writing to report a possible circular locking dependency vulnerabili= ty in the `ocfs2` subsystem, detected by the Lockdep validation mechanism a= s well as our custom fuzzing tool, RacePilot. The bug involves an ABBA dead= lock concerning the system inode allocations, `fs_reclaim`, and `osb->nfs_s= ync_rwlock`. We observed this on the Linux kernel version 6.18.0-08691-g206= 1f18ad76e-dirty. Call Trace & Context =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D WARNING: possible circular locking dependency detected kswapd1/95 is trying to acquire lock: ffff8880005889c0 (&ocfs2_sysfile_lock_key[ORPHAN_DIR_SYSTEM_INODE]){+.+.}-{= 4:4}, at: inode_lock include/linux/fs.h:1027 [inline] ffff8880005889c0 (&ocfs2_sysfile_lock_key[ORPHAN_DIR_SYSTEM_INODE]){+.+.}-{= 4:4}, at: ocfs2_wipe_inode+0x2df/0x1380 fs/ocfs2/inode.c:852 but task is already holding lock: ffff8880533acbd0 (&osb->nfs_sync_rwlock){.+.+}-{4:4}, at: ocfs2_nfs_sync_lo= ck+0xe9/0x2f0 fs/ocfs2/dlmglue.c:2875 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #3 (&osb->nfs_sync_rwlock){.+.+}-{4:4}: down_read+0x9b/0x460 kernel/locking/rwsem.c:1537 ocfs2_nfs_sync_lock+0xe9/0x2f0 fs/ocfs2/dlmglue.c:2875 ocfs2_delete_inode fs/ocfs2/inode.c:1106 [inline] ocfs2_evict_inode+0x2c7/0x1430 fs/ocfs2/inode.c:1297 evict+0x3b3/0xaa0 fs/inode.c:850 ... balance_pgdat+0xb75/0x1a20 mm/vmscan.c:7270 kswapd+0x576/0xac0 mm/vmscan.c:7537 -> #2 (fs_reclaim){+.+.}-{0:0}: __fs_reclaim_acquire mm/page_alloc.c:4264 [inline] fs_reclaim_acquire+0x102/0x150 mm/page_alloc.c:4278 ... slab_alloc_node mm/slub.c:5234 [inline] kmalloc_noprof include/linux/slab.h:957 [inline] ocfs2_reserve_new_metadata_blocks+0xed/0xb50 fs/ocfs2/suballoc.c:968 ocfs2_mknod+0xa65/0x24e0 fs/ocfs2/namei.c:350 ocfs2_create+0x180/0x430 fs/ocfs2/namei.c:676 ... do_sys_open fs/open.c:1436 [inline] __x64_sys_openat+0x13f/0x1f0 fs/open.c:1447 -> #1 (&ocfs2_sysfile_lock_key[INODE_ALLOC_SYSTEM_INODE]){+.+.}-{4:4}: down_write+0x91/0x200 kernel/locking/rwsem.c:1590 inode_lock include/linux/fs.h:1027 [inline] ocfs2_remove_inode+0x15e/0x8e0 fs/ocfs2/inode.c:731 ocfs2_wipe_inode+0x652/0x1380 fs/ocfs2/inode.c:894 ocfs2_delete_inode fs/ocfs2/inode.c:1155 [inline] ocfs2_evict_inode+0x69e/0x1430 fs/ocfs2/inode.c:1297 ... -> #0 (&ocfs2_sysfile_lock_key[ORPHAN_DIR_SYSTEM_INODE]){+.+.}-{4:4}: lock_acquire+0x17b/0x330 kernel/locking/lockdep.c:5825 down_write+0x91/0x200 kernel/locking/rwsem.c:1590 inode_lock include/linux/fs.h:1027 [inline] ocfs2_wipe_inode+0x2df/0x1380 fs/ocfs2/inode.c:852 ocfs2_delete_inode fs/ocfs2/inode.c:1155 [inline] ocfs2_evict_inode+0x69e/0x1430 fs/ocfs2/inode.c:1297 ... kswapd+0x576/0xac0 mm/vmscan.c:7537 other info that might help us debug this: Chain exists of: &ocfs2_sysfile_lock_key[ORPHAN_DIR_SYSTEM_INODE] --> fs_reclaim --> &osb-= >nfs_sync_rwlock Possible unsafe locking scenario: CPU0 CPU1 ---- ---- rlock(&osb->nfs_sync_rwlock); lock(fs_reclaim); lock(&osb->nfs_sync_rwlock); lock(&ocfs2_sysfile_lock_key[ORPHAN_DIR_SYSTEM_INODE]); *** DEADLOCK *** =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Execution Flow & Code Context The `kswapd` thread processes eviction logic for unused inodes in the dcach= e queue holding the `fs_reclaim` lock contexts. When a unlinked inode enter= s `ocfs2_evict_inode()`, it calls into `ocfs2_delete_inode()`. The deletion= pathway attempts to securely clear traces of the inode globally by locking= internal structure mutexes including the `nfs_sync_rwlock` and `ORPHAN_DIR= _SYSTEM_INODE` lock: ```c // fs/ocfs2/inode.c static void ocfs2_delete_inode(struct inode *inode) { ... status =3D ocfs2_nfs_sync_lock(OCFS2_SB(inode->i_sb), 0); // <-- Takes nfs= _sync_rwlock ... status =3D ocfs2_wipe_inode(inode, di_bh); ... } static int ocfs2_wipe_inode(struct inode *inode, struct buffer_head *di_bh) { ... inode_lock(orphan_dir_inode); // <-- Takes ocfs2_sysfile_lock_key[ORPHAN_= DIR] status =3D ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); ... } ``` Concurrently, another thread could invoke file creation (`ocfs2_create` ...= `ocfs2_reserve_new_metadata_blocks`), requiring memory. In this path, if i= t pauses allocation, it calls `kmalloc` invoking `fs_reclaim_acquire`, maki= ng `&ocfs2_sysfile_lock_key` -> `fs_reclaim` dependent loops since some met= adata modifications naturally grasp system file cluster locks to protect al= loc structures. Root Cause Analysis A circular locking deadlock exists because `ocfs2_evict_inode` is triggered= directly under memory `fs_reclaim` shrinker pathways (e.g., from `kswapd`)= . When `kswapd` frees the dentry structures, `evict` is processed synchrono= usly in the reclaim context, which in OCFS2 takes complex subsystem locks s= panning DLM locks like `nfs_sync_rwlock` and various `sysfile_lock_key` var= iants intended to orchestrate global orphan cleanups. If any other arbitrar= y thread operating on creation pathways sleeps acquiring physical block pag= es (`fs_reclaim` needed), the paths will intertwine resulting in lock cycle= s. Unfortunately, we were unable to generate a reproducer for this bug. Potential Impact This circular dependency can stall the `kswapd` daemon globally halting mem= ory management tasks, leading to system OOM (Out of Memory) panics and file= system lock-ups. This constitutes a persistent local Denial of Service (DoS= ) capability triggered arbitrarily under low-free memory workloads with orp= haned inodes. Proposed Fix To mitigate the deadlock, `ocfs2_evict_inode` must defer the heavy `ocfs2_d= elete_inode` operations to a worker queue outside the memory reclaim contex= t if the current process is a memory reclaimer (such as `kswapd` signaled b= y `current->flags & PF_MEMALLOC`). ```diff --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -1292,8 +1292,16 @@ void ocfs2_evict_inode(struct inode *inode) write_inode_now(inode, 1); =20 if (!inode->i_nlink || (OCFS2_I(inode)->ip_flags & OCFS2_INODE_MAYBE_ORPHANED)) { - ocfs2_delete_inode(inode); + if (current->flags & PF_MEMALLOC) { + /* + * Defer deleting orphan inodes if doing memory reclaim + * to avoid lockdep circular dependencies. + */ + ocfs2_queue_orphan_scan(OCFS2_SB(inode->i_sb)); + } else { + ocfs2_delete_inode(inode); + } } else { truncate_inode_pages_final(&inode->i_data); } ``` We would be highly honored if this could be of any help. Best regards, RacePilot Team