diff options
author | Christoph Hellwig <hch@lst.de> | 2023-08-02 17:41:30 +0200 |
---|---|---|
committer | Christian Brauner <brauner@kernel.org> | 2023-08-11 13:15:04 +0200 |
commit | 8d945b595ed07db13fef1f3311ad456c97941930 (patch) | |
tree | 081d94cc85e1d7f48b68876c5f3c1679e8dd94ee /fs/xfs | |
parent | 8bed1783751fc8d0a5a263dcf87838a2fa570953 (diff) |
xfs: drop s_umount over opening the log and RT devices
Just like get_tree_bdev needs to drop s_umount when opening the main
device, we need to do the same for the xfs log and RT devices to avoid a
potential lock order reversal with s_unmount for the mark_dead path.
It might be preferable to just drop s_umount over ->fill_super entirely,
but that will require a fairly massive audit first, so we'll do the easy
version here first.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Message-Id: <20230802154131.2221419-12-hch@lst.de>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_super.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 46d0cbe2b5f8..97ef41acb03d 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -462,17 +462,24 @@ STATIC int xfs_open_devices( struct xfs_mount *mp) { - struct block_device *ddev = mp->m_super->s_bdev; + struct super_block *sb = mp->m_super; + struct block_device *ddev = sb->s_bdev; struct block_device *logdev = NULL, *rtdev = NULL; int error; /* + * blkdev_put() can't be called under s_umount, see the comment + * in get_tree_bdev() for more details + */ + up_write(&sb->s_umount); + + /* * Open real time and log devices - order is important. */ if (mp->m_logname) { error = xfs_blkdev_get(mp, mp->m_logname, &logdev); if (error) - return error; + goto out_relock; } if (mp->m_rtname) { @@ -510,7 +517,10 @@ xfs_open_devices( mp->m_logdev_targp = mp->m_ddev_targp; } - return 0; + error = 0; +out_relock: + down_write(&sb->s_umount); + return error; out_free_rtdev_targ: if (mp->m_rtdev_targp) @@ -523,7 +533,7 @@ xfs_open_devices( out_close_logdev: if (logdev && logdev != ddev) blkdev_put(logdev, mp); - return error; + goto out_relock; } /* |