All of lore.kernel.org
 help / color / mirror / Atom feed
From: "syzbot" <syzbot@kernel.org>
To: syzkaller-upstream-moderation@googlegroups.com
Cc: syzbot@lists.linux.dev
Subject: [PATCH RFC] fs/ntfs3: use ni_lock_dir() in ntfs_readdir()
Date: Tue, 13 Oct 2026 04:26:10 +0000 (UTC)	[thread overview]
Message-ID: <3a72d0ff-b0a3-41de-b2d7-bb629cf3ca02@mail.kernel.org> (raw)

A circular locking dependency warning is detected by lockdep between
&ni->ni_lock and mapping.invalidate_lock when getdents64() writes into a
memory-mapped buffer while an operation such as fallocate() runs
concurrently on a regular file:

 WARNING: possible circular locking dependency detected
 task is trying to acquire lock:
 ffff88819b6dbb20 (mapping.invalidate_lock#3){++++}-{4:4}, at:
 filemap_fault+0x6e0/0x13c0 mm/filemap.c:3585
 but task is already holding lock:
 ffff88819b6997e8 (&ni->ni_lock/5){+.+.}-{4:4}, at:
 ntfs_readdir+0x717/0xf70 fs/ntfs3/dir.c:541
 which lock already depends on the new lock.

 the existing dependency chain (in reverse order) is:

  -> #1 (&ni->ni_lock/5){+.+.}-{4:4}:
        ni_lock fs/ntfs3/ntfs_fs.h:1247 [inline]
        ntfs_fallocate+0x56a/0x1080 fs/ntfs3/file.c:535
        vfs_fallocate+0x663/0x7f0 fs/open.c:338
        ioctl_preallocate fs/ioctl.c:289 [inline]
        file_ioctl+0x5db/0x7e0 fs/ioctl.c:332
        do_vfs_ioctl+0xc2a/0x1550 fs/ioctl.c:576

  -> #0 (mapping.invalidate_lock#3){++++}-{4:4}:
        filemap_invalidate_lock_shared include/linux/fs.h:1089 [inline]
        filemap_fault+0x6e0/0x13c0 mm/filemap.c:3585
        __do_fault+0x138/0x2a0 mm/memory.c:5565
        handle_pte_fault mm/memory.c:6558 [inline]
        __handle_mm_fault mm/memory.c:6707 [inline]
        handle_mm_fault+0x100a/0x28a0 mm/memory.c:6876
        do_user_addr_fault+0x746/0x1340 arch/x86/mm/fault.c:1394
        exc_page_fault+0x6a/0xc0 arch/x86/mm/fault.c:1536
        filldir64+0x2bc/0x620 fs/readdir.c:-1
        dir_emit include/linux/fs.h:3610 [inline]
        ntfs_dir_emit fs/ntfs3/dir.c:388 [inline]
        ntfs_read_hdr+0x8a7/0xc10 fs/ntfs3/dir.c:429
        ntfs_readdir+0x9ab/0xf70 fs/ntfs3/dir.c:589
        iterate_dir+0x3ea/0x8a0 fs/readdir.c:114
        __do_sys_getdents64 fs/readdir.c:404 [inline]

The warning occurs because ntfs_fallocate() on a regular file acquires
mapping.invalidate_lock and then calls ni_lock(), which locks the regular
file inode's ni_lock with the default subclass NTFS_INODE_MUTEX_NORMAL
(subclass 5). Meanwhile, ntfs_readdir() on a directory inode also uses
ni_lock() with subclass 5, and while holding the lock across directory
traversal, calls dir_emit() to fill directory entries into the user buffer.
If that buffer is backed by a memory-mapped file, writing to it triggers a
page fault (filemap_fault()), which acquires the mapped file's
mapping.invalidate_lock. Because lockdep sees mapping.invalidate_lock ->
ni_lock (subclass 5) in fallocate and ni_lock (subclass 5) ->
mapping.invalidate_lock in readdir, it flags a circular locking dependency.

This is a false positive because the two operations involve distinct
inodes: readdir holds the mutex of the directory inode, while the page
fault acquires the invalidate_lock of the regular file whose pages back the
user buffer, so an actual deadlock cannot occur.

In ntfs3, directory inodes are intended to be locked with ni_lock_dir(),
which uses the lockdep subclass NTFS_INODE_MUTEX_PARENT (subclass 6). This
subclass hierarchy is already used by other directory operations like
ntfs_lookup(), ntfs_create_inode(), ntfs_link(), ntfs_unlink(), and
ntfs_rename(). Replace ni_lock() with ni_lock_dir() in ntfs_readdir() when
loading subrecords and when traversing directory metadata. This changes the
directory lock subclass to NTFS_INODE_MUTEX_PARENT (6), establishing the
hierarchy ni_lock_dir (subclass 6) -> mapping.invalidate_lock -> ni_lock
(subclass 5) and eliminating the false lockdep warning.

Fixes: d62cf685d12e ("fs/ntfs3: hold ni_lock across readdir metadata walk")
Assisted-by: Gemini:gemini-3.8-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+7736960b837908f3a81d@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=7736960b837908f3a81d
Link: https://syzkaller.appspot.com/ai_job?id=fae916f3-c2b4-47da-86b5-063a011b5c01
To: "Konstantin Komarov" <almaz.alexandrovich@paragon-software.com>
To: <ntfs3@lists.linux.dev>
To: "ZhengYuan Huang" <gality369@gmail.com>
Cc: <linux-kernel@vger.kernel.org>

---
diff --git a/fs/ntfs3/dir.c b/fs/ntfs3/dir.c
index eb9152e9f..8bf62d2fb 100644
--- a/fs/ntfs3/dir.c
+++ b/fs/ntfs3/dir.c
@@ -522,7 +522,7 @@ static int ntfs_readdir(struct file *file, struct dir_context *ctx)
 		 * Load all subrecords to avoid 'write' access to 'ni' during
 		 * directory reading.
 		 */
-		ni_lock(ni);
+		ni_lock_dir(ni);
 		if (!ni->mi_loaded && ni->attr_list.size) {
 			err = ni_load_all_mi(ni);
 			if (!err)
@@ -538,7 +538,7 @@ static int ntfs_readdir(struct file *file, struct dir_context *ctx)
 	 * once is not enough if concurrent writeback can still compact ATTR_LIST
 	 * entries and free the record that ntfs_read_hdr() is currently walking.
 	 */
-	ni_lock(ni);
+	ni_lock_dir(ni);
 
 	root = indx_get_root(&ni->dir, ni, NULL, NULL);
 	if (!root) {


base-commit: 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907
-- 
This is an AI-generated patch subject to moderation.
Reply with '#syz upstream' to Sign-off the patch as a human author
and send it to the upstream kernel mailing lists.
Reply with '#syz reject' to reject it ('#syz unreject' to undo).

See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
You can comment on the patch as usual, syzbot will try to address
the comments and send a new version of the patch if necessary.
syzbot engineers can be reached at syzkaller@googlegroups.com.

             reply	other threads:[~2026-10-13  4:26 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13  4:26 syzbot [this message]
2026-10-13 19:34 ` [PATCH RFC] fs/ntfs3: use ni_lock_dir() in ntfs_readdir() Aleksandr Nogikh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3a72d0ff-b0a3-41de-b2d7-bb629cf3ca02@mail.kernel.org \
    --to=syzbot@kernel.org \
    --cc=syzbot@lists.linux.dev \
    --cc=syzkaller-upstream-moderation@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.