hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAC63K CVE: NA
--------------------------------
When I mount a corrupt xfs image, mount process hang all the time, the stack as follows:
[root@testvm ~]# cat /proc/425/stack [<0>] xfs_wait_buftarg+0x5a/0x360 [<0>] xfs_mountfs+0x591/0xc90 [<0>] xfs_fc_fill_super+0x792/0xc80 [<0>] get_tree_bdev+0x1ec/0x3a0 [<0>] xfs_fc_get_tree+0x19/0x30 [<0>] vfs_get_tree+0x2f/0x110 [<0>] path_mount+0x8ab/0x1150 [<0>] do_mount+0x91/0xc0 [<0>] __se_sys_mount+0x14a/0x220 [<0>] __x64_sys_mount+0x29/0x40 [<0>] do_syscall_64+0x6c/0xe0 [<0>] entry_SYSCALL_64_after_hwframe+0x62/0xc7
During buffer recovery, if the superblock buffer is modified, we also need to update the content of the mount point (mp). In this situation, if we encounter an error, we will go to out_release and release the xfs_buf. However, this is not enough because the xfs_buf's log item has been initialized and is held by the buffer log item in xlog_recover_do_reg_buffer().
Fixing this issue is straightforward: we need to set the error and add the xfs_buf to the buffer_list in such situations. This allows it to be handled by the normal buffer write process. The filesystem will be shut down before submission in xlog_do_recovery_pass() because the log recovery encountered an error. As a result, the xfs_buf will be released correctly.
Fixes: 6fb62b3ffacb ("xfs: fix the problem of mount failure caused by not refreshing mp->m_sb") Signed-off-by: Long Li leo.lilong@huawei.com --- fs/xfs/xfs_buf_item_recover.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c index 2383cc2d0354..f78476180bb7 100644 --- a/fs/xfs/xfs_buf_item_recover.c +++ b/fs/xfs/xfs_buf_item_recover.c @@ -980,7 +980,7 @@ xlog_recover_buf_commit_pass2( bp->b_ops->verify_write(bp); error = bp->b_error; if (error) - goto out_release; + goto out_writebuf;
if (be32_to_cpu(sb->sb_agcount) > mp->m_sb.sb_agcount) { error = xfs_initialize_perag(mp, @@ -988,13 +988,14 @@ xlog_recover_buf_commit_pass2( be64_to_cpu(sb->sb_dblocks), &mp->m_maxagi); if (error) - goto out_release; + goto out_writebuf; }
xfs_sb_from_disk(&mp->m_sb, sb); } }
+out_writebuf: /* * Perform delayed write on the buffer. Asynchronous writes will be * slower when taking into account all the buffers to be flushed.