[PATCH] ntfs: avoid self-deadlock during inode eviction
From: Hyunchul Lee
Date: Thu Jul 02 2026 - 01:28:29 EST
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.
Signed-off-by: Hyunchul Lee <hyc.lee@xxxxxxxxx>
---
fs/ntfs/aops.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
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,
---
base-commit: ec050fc4cf17d341e08c8e25dd9dd6af37bb2e67
change-id: 20260702-fix-deadlock-inode-eviction-086ee99bd59d
Best regards,
--
Thanks,
Hyunchul