xfs: document the invalidate_bdev call in invalidate_bdev
Copy and paste the commit message from Darrick into a comment to explain the seemingly odd invalidate_bdev in xfs_shutdown_devices. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Message-Id: <20230809220545.1308228-8-hch@lst.de> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
35a93b148b
commit
1a0a5dad67
@ -410,6 +410,32 @@ STATIC void
|
||||
xfs_shutdown_devices(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
/*
|
||||
* Udev is triggered whenever anyone closes a block device or unmounts
|
||||
* a file systemm on a block device.
|
||||
* The default udev rules invoke blkid to read the fs super and create
|
||||
* symlinks to the bdev under /dev/disk. For this, it uses buffered
|
||||
* reads through the page cache.
|
||||
*
|
||||
* xfs_db also uses buffered reads to examine metadata. There is no
|
||||
* coordination between xfs_db and udev, which means that they can run
|
||||
* concurrently. Note there is no coordination between the kernel and
|
||||
* blkid either.
|
||||
*
|
||||
* On a system with 64k pages, the page cache can cache the superblock
|
||||
* and the root inode (and hence the root directory) with the same 64k
|
||||
* page. If udev spawns blkid after the mkfs and the system is busy
|
||||
* enough that it is still running when xfs_db starts up, they'll both
|
||||
* read from the same page in the pagecache.
|
||||
*
|
||||
* The unmount writes updated inode metadata to disk directly. The XFS
|
||||
* buffer cache does not use the bdev pagecache, so it needs to
|
||||
* invalidate that pagecache on unmount. If the above scenario occurs,
|
||||
* the pagecache no longer reflects what's on disk, xfs_db reads the
|
||||
* stale metadata, and fails to find /a. Most of the time this succeeds
|
||||
* because closing a bdev invalidates the page cache, but when processes
|
||||
* race, everyone loses.
|
||||
*/
|
||||
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
|
||||
blkdev_issue_flush(mp->m_logdev_targp->bt_bdev);
|
||||
invalidate_bdev(mp->m_logdev_targp->bt_bdev);
|
||||
|
Loading…
x
Reference in New Issue
Block a user