Message ID | 20250111070544.896052-1-leo.lilong@huawei.com (mailing list archive) |
---|---|
State | Accepted, archived |
Headers | show |
Series | [v3] xfs: fix mount hang during primary superblock recovery failure | expand |
On Sat, 11 Jan 2025 15:05:44 +0800, Long Li wrote: > When mounting an image containing a log with sb modifications that require > log replay, the mount process hang all the time and stack as follows: > > [root@localhost ~]# cat /proc/557/stack > [<0>] xfs_buftarg_wait+0x31/0x70 > [<0>] xfs_buftarg_drain+0x54/0x350 > [<0>] xfs_mountfs+0x66e/0xe80 > [<0>] xfs_fs_fill_super+0x7f1/0xec0 > [<0>] get_tree_bdev_flags+0x186/0x280 > [<0>] get_tree_bdev+0x18/0x30 > [<0>] xfs_fs_get_tree+0x1d/0x30 > [<0>] vfs_get_tree+0x2d/0x110 > [<0>] path_mount+0xb59/0xfc0 > [<0>] do_mount+0x92/0xc0 > [<0>] __x64_sys_mount+0xc2/0x160 > [<0>] x64_sys_call+0x2de4/0x45c0 > [<0>] do_syscall_64+0xa7/0x240 > [<0>] entry_SYSCALL_64_after_hwframe+0x76/0x7e > > [...] Applied to for-next, thanks! [1/1] xfs: fix mount hang during primary superblock recovery failure commit: efebe42d95fbba91dca6e3e32cb9e0612eb56de5 Best regards,
diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c index 3d0c6402cb36..6b10390ad3d2 100644 --- a/fs/xfs/xfs_buf_item_recover.c +++ b/fs/xfs/xfs_buf_item_recover.c @@ -1079,7 +1079,7 @@ xlog_recover_buf_commit_pass2( error = xlog_recover_do_primary_sb_buffer(mp, item, bp, buf_f, current_lsn); if (error) - goto out_release; + goto out_writebuf; /* Update the rt superblock if we have one. */ if (xfs_has_rtsb(mp) && mp->m_rtsb_bp) { @@ -1096,6 +1096,15 @@ xlog_recover_buf_commit_pass2( xlog_recover_do_reg_buffer(mp, item, bp, buf_f, current_lsn); } + /* + * Buffer held by buf log item during 'normal' buffer recovery must + * be committed through buffer I/O submission path to ensure proper + * release. When error occurs during sb buffer recovery, log shutdown + * will be done before submitting buffer list so that buffers can be + * released correctly through ioend failure path. + */ +out_writebuf: + /* * Perform delayed write on the buffer. Asynchronous writes will be * slower when taking into account all the buffers to be flushed.