Commit da9b6a5c authored by Long Li's avatar Long Li
Browse files

xfs: fix mount hung while sb recover fail

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: 6fb62b3f ("xfs: fix the problem of mount failure caused by not refreshing mp->m_sb")
Signed-off-by: default avatarLong Li <leo.lilong@huawei.com>
parent 2abe7490
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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.