syzbot reported a hung task in hfs_mdb_commit where a deadlock occurs between the MDB buffer lock and the folio lock. The deadlock happens because hfs_mdb_commit() holds the mdb_bh lock while calling sb_bread(), which attempts to acquire the lock on the same folio. thread1: hfs_mdb_commit ->lock_buffer(HFS_SB(sb)->mdb_bh); ->bh = sb_bread(sb, block); ...->folio_lock(folio) thread2: ->blkdev_writepages() ->writeback_iter() ->writeback_get_folio() ->folio_lock(folio) ->block_write_full_folio() __block_write_full_folio() ->lock_buffer(bh) This patch removes the lock_buffer(mdb_bh) call. Since hfs_mdb_commit() is typically called via VFS paths where the superblock is already appropriately protected (e.g., during sync or unmount), the additional low-level buffer lock may be redundant and is the direct cause of the lock inversion. I am seeking comments on whether this VFS-level protection is sufficient for HFS metadata consistency or if a more granular locking approach is preferred. Link: https://syzkaller.appspot.com/bug?extid=1e3ff4b07c16ca0f6fe2 Reported-by: syzbot Signed-off-by: Jinchao Wang --- fs/hfs/mdb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c index 53f3fae60217..c641adb94e6f 100644 --- a/fs/hfs/mdb.c +++ b/fs/hfs/mdb.c @@ -268,7 +268,6 @@ void hfs_mdb_commit(struct super_block *sb) if (sb_rdonly(sb)) return; - lock_buffer(HFS_SB(sb)->mdb_bh); if (test_and_clear_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags)) { /* These parameters may have been modified, so write them back */ mdb->drLsMod = hfs_mtime(); @@ -340,7 +339,6 @@ void hfs_mdb_commit(struct super_block *sb) size -= len; } } - unlock_buffer(HFS_SB(sb)->mdb_bh); } void hfs_mdb_close(struct super_block *sb) -- 2.43.0