On Sat, Feb 04, 2023 at 02:58:38PM +0000, Shiyang Ruan wrote: > This patch is inspired by Dan's "mm, dax, pmem: Introduce > dev_pagemap_failure()"[1]. With the help of dax_holder and > ->notify_failure() mechanism, the pmem driver is able to ask filesystem > (or mapped device) on it to unmap all files in use and notify processes > who are using those files. ..... > @@ -182,12 +188,24 @@ xfs_dax_notify_failure( > struct xfs_mount *mp = dax_holder(dax_dev); > u64 ddev_start; > u64 ddev_end; > + int error; > > if (!(mp->m_super->s_flags & SB_BORN)) { > xfs_warn(mp, "filesystem is not ready for notify_failure()!"); > return -EIO; > } > > + if (mf_flags & MF_MEM_PRE_REMOVE) { > + xfs_info(mp, "device is about to be removed!"); > + down_write(&mp->m_super->s_umount); > + error = sync_filesystem(mp->m_super); > + /* invalidate_inode_pages2() invalidates dax mapping */ > + super_drop_pagecache(mp->m_super, invalidate_inode_pages2); > + up_write(&mp->m_super->s_umount); I really don't like this. super_drop_pagecache() doesn't guarantee that everything is removed from cache. It is racy - it doesn't touch inodes being freed or being instantiated, nor does it prevent concurrent accesses to the inodes from re-instantiating page cache pages and dirtying them after the inode has been scanned by super_drop_pagecache(). If we are about to remove the block device and we want to guarantee that the filesystem is cleaned and stable before the device gets yanked out from under running applications, then we have to guarantee that we stall the running applications trying to modify the filesystem between the MF_MEM_PRE_REMOVE and the actual removal event that then shuts down the filesystem. Invalidating the page cache is not enough to guarantee this. Keep in mind that we're going to walk the rmap after writing the data to kill any processes that have mmap()d files in the filesystem after we've dropped the page cache - the page cache invalidation doesn't change this at all - and this will kill any active userspace DAX mappings before the device is unplugged. So I don't actually see how walking the page cache to invalidate it here actually helps "invalidate dax mapping" reliably as new write page faults on dax VMAs can still occur between super_drop_pagecache() and the rmap walk triggering kills on processes with DAX mapped VMAs. We also don't care if read-only operations race with device unplug - they are going to get EIO the moment the device is actually unplugged or the filesystem is shutdown anyway, so it doesn't matter if reads race with the device remove event. Hence all we really care about here is not dirtying the filesystem after we've started processing the MF_MEM_PRE_REMOVE event. Realistically, I think we need to freeze the filesystem here to prevent racing modifications occurring during the rmap + VMA walk + proc kill. That could be write() IO dirtying new data or other transactions running dirtying the journal/metadata. Both sync_filesystem() and super_drop_pagecache() operate on current state - they don't prevent future dax mapping instantiation or dirtying from happening on the device, so they don't prevent this... Cheers, Dave. -- Dave Chinner david@xxxxxxxxxxxxx