git: 3dc5f8e19d8c - main - ffs: wait for trims earlier during unmount to avoid panic
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 08 Apr 2022 17:23:05 UTC
The branch main has been updated by chs: URL: https://cgit.FreeBSD.org/src/commit/?id=3dc5f8e19d8c975a5e27752d65f9aa91d67c9c9e commit 3dc5f8e19d8c975a5e27752d65f9aa91d67c9c9e Author: Chuck Silvers <chs@FreeBSD.org> AuthorDate: 2022-04-08 17:19:40 +0000 Commit: Chuck Silvers <chs@FreeBSD.org> CommitDate: 2022-04-08 17:19:40 +0000 ffs: wait for trims earlier during unmount to avoid panic All softdep processing is supposed to be completed by softdep_flushfiles() and no more deps are supposed to be created after that, but if a pending trim completes after softdep_flushfiles() and before softdep_unmount() then the blkfree that is performed by ffs_blkfree_trim_task() will create a dep when none should exist, and if softdep_unmount() is called before that dep is freed then the kernel will panic. Prevent this by waiting for trims to complete earlier in the unmount process, in ffs_flushfiles(), so that any deps will be freed and any modified CG buffers will be flushed by the final fsync of the devvp in ffs_flushfiles() as intended. Reviewed by: mckusick, kib Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D34806 --- sys/ufs/ffs/ffs_vfsops.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 77361731202a..e9cbc962cd78 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -1423,9 +1423,7 @@ ffs_unmount(mp, mntflags) if (susp) vfs_write_resume(mp, VR_START_WRITE); if (ump->um_trim_tq != NULL) { - while (ump->um_trim_inflight != 0) - pause("ufsutr", hz); - taskqueue_drain_all(ump->um_trim_tq); + MPASS(ump->um_trim_inflight == 0); taskqueue_free(ump->um_trim_tq); free (ump->um_trimhash, M_TRIM); } @@ -1539,6 +1537,20 @@ ffs_flushfiles(mp, flags, td) if (qerror == 0 && (error = vflush(mp, 0, flags, td)) != 0) return (error); + /* + * If this is a forcible unmount and there were any files that + * were unlinked but still open, then vflush() will have + * truncated and freed those files, which might have started + * some trim work. Wait here for any trims to complete + * and process the blkfrees which follow the trims. + * This may create more dirty devvp buffers and softdep deps. + */ + if (ump->um_trim_tq != NULL) { + while (ump->um_trim_inflight != 0) + pause("ufsutr", hz); + taskqueue_drain_all(ump->um_trim_tq); + } + /* * Flush filesystem metadata. */