diff options
| author | Hyunchul Lee <hyc.lee@gmail.com> | 2026-07-02 14:28:16 +0900 |
|---|---|---|
| committer | Namjae Jeon <linkinjeon@kernel.org> | 2026-07-06 20:26:05 +0900 |
| commit | 77dc384207d5fa63ba97c3bf3285fe1215a1cbf6 (patch) | |
| tree | aaf59efcd29fec1f20e82579740c55bc3055ad14 | |
| parent | f72df3a4c33b64de3418ec74d1ad4f028e09d161 (diff) | |
| download | linux-next-77dc384207d5fa63ba97c3bf3285fe1215a1cbf6.tar.gz linux-next-77dc384207d5fa63ba97c3bf3285fe1215a1cbf6.zip | |
ntfs: avoid self-deadlock during inode eviction
An attribute-list update performed while allocating clusters can drop the
last reference to the temporary attribute inode. Evicting that inode
drops its reference to the base inode and can invoke ntfs_drop_big_inode()
for the base inode from within the base inode's own writeback path.
If the base inode is unlinked, ntfs_drop_big_inode() calls
truncate_setsize(), which waits for the inode's folio writeback to
complete. The same writeback worker is responsible for completing that
writeback, so it waits for itself indefinitely.
Prevent this self-deadlock by grabbing a reference to the base inode at the
beginning of ntfs_writepages() and releasing it at the end of the function.
This defers eviction until all bios have been submitted, allowing the wait
for folio writeback to complete safely.
Fixes: b041ca562526 ("ntfs: update iomap and address space operations")
Cc: stable@vger.kernel.org
Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
| -rw-r--r-- | fs/ntfs/aops.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index 1fbf832ad165..88e5b2def66c 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c @@ -251,6 +251,8 @@ static int ntfs_writepages(struct address_space *mapping, .wbc = wbc, .ops = &ntfs_writeback_ops, }; + bool need_iput = false; + int ret; if (NVolShutdown(ni->vol)) return -EIO; @@ -267,7 +269,20 @@ static int ntfs_writepages(struct address_space *mapping, return -EOPNOTSUPP; } - return iomap_writepages(&wpc); + /* + * Prevent eviction in writeback to avoid deadlock in + * ntfs_drop_big_inode(). + */ + if ((ni->type == AT_DATA || ni->type == AT_INDEX_ALLOCATION) && + igrab(inode)) + need_iput = true; + + ret = iomap_writepages(&wpc); + + if (need_iput) + iput(inode); + + return ret; } static int ntfs_swap_activate(struct swap_info_struct *sis, |
