Date: Thu, 19 Nov 2020 09:09:19 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r367836 - in stable/12/sys: dev/acpica dev/xen/control kern sys Message-ID: <202011190909.0AJ99JCX004145@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Thu Nov 19 09:09:19 2020 New Revision: 367836 URL: https://svnweb.freebsd.org/changeset/base/367836 Log: MFC r367398: Suspend all writeable local filesystems on power suspend. Modified: stable/12/sys/dev/acpica/acpi.c stable/12/sys/dev/xen/control/control.c stable/12/sys/kern/vfs_mount.c stable/12/sys/sys/mount.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/acpica/acpi.c ============================================================================== --- stable/12/sys/dev/acpica/acpi.c Thu Nov 19 08:16:45 2020 (r367835) +++ stable/12/sys/dev/acpica/acpi.c Thu Nov 19 09:09:19 2020 (r367836) @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <sys/ctype.h> #include <sys/linker.h> +#include <sys/mount.h> #include <sys/power.h> #include <sys/sbuf.h> #include <sys/sched.h> @@ -3045,6 +3046,7 @@ acpi_EnterSleepState(struct acpi_softc *sc, int state) EVENTHANDLER_INVOKE(power_suspend_early); stop_all_proc(); + suspend_all_fs(); EVENTHANDLER_INVOKE(power_suspend); #ifdef EARLY_AP_STARTUP @@ -3204,6 +3206,7 @@ backout: } #endif + resume_all_fs(); resume_all_proc(); EVENTHANDLER_INVOKE(power_resume); Modified: stable/12/sys/dev/xen/control/control.c ============================================================================== --- stable/12/sys/dev/xen/control/control.c Thu Nov 19 08:16:45 2020 (r367835) +++ stable/12/sys/dev/xen/control/control.c Thu Nov 19 09:09:19 2020 (r367836) @@ -113,6 +113,7 @@ __FBSDID("$FreeBSD$"); #include <sys/filedesc.h> #include <sys/kdb.h> #include <sys/module.h> +#include <sys/mount.h> #include <sys/namei.h> #include <sys/proc.h> #include <sys/reboot.h> @@ -204,6 +205,7 @@ xctrl_suspend() xs_lock(); stop_all_proc(); xs_unlock(); + suspend_all_fs(); EVENTHANDLER_INVOKE(power_suspend); #ifdef EARLY_AP_STARTUP @@ -317,6 +319,7 @@ xctrl_suspend() } #endif + resume_all_fs(); resume_all_proc(); EVENTHANDLER_INVOKE(power_resume); Modified: stable/12/sys/kern/vfs_mount.c ============================================================================== --- stable/12/sys/kern/vfs_mount.c Thu Nov 19 08:16:45 2020 (r367835) +++ stable/12/sys/kern/vfs_mount.c Thu Nov 19 09:09:19 2020 (r367836) @@ -2057,3 +2057,67 @@ vfs_oexport_conv(const struct oexport_args *oexp, stru bcopy(oexp, exp, sizeof(*oexp)); exp->ex_numsecflavors = 0; } + +/* + * Suspend write operations on all local writeable filesystems. Does + * full sync of them in the process. + * + * Iterate over the mount points in reverse order, suspending most + * recently mounted filesystems first. It handles a case where a + * filesystem mounted from a md(4) vnode-backed device should be + * suspended before the filesystem that owns the vnode. + */ +void +suspend_all_fs(void) +{ + struct mount *mp; + int error; + + mtx_lock(&mountlist_mtx); + TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) { + error = vfs_busy(mp, MBF_MNTLSTLOCK | MBF_NOWAIT); + if (error != 0) + continue; + if ((mp->mnt_flag & (MNT_RDONLY | MNT_LOCAL)) != MNT_LOCAL || + (mp->mnt_kern_flag & MNTK_SUSPEND) != 0) { + mtx_lock(&mountlist_mtx); + vfs_unbusy(mp); + continue; + } + error = vfs_write_suspend(mp, 0); + if (error == 0) { + MNT_ILOCK(mp); + MPASS((mp->mnt_kern_flag & MNTK_SUSPEND_ALL) == 0); + mp->mnt_kern_flag |= MNTK_SUSPEND_ALL; + MNT_IUNLOCK(mp); + mtx_lock(&mountlist_mtx); + } else { + printf("suspend of %s failed, error %d\n", + mp->mnt_stat.f_mntonname, error); + mtx_lock(&mountlist_mtx); + vfs_unbusy(mp); + } + } + mtx_unlock(&mountlist_mtx); +} + +void +resume_all_fs(void) +{ + struct mount *mp; + + mtx_lock(&mountlist_mtx); + TAILQ_FOREACH(mp, &mountlist, mnt_list) { + if ((mp->mnt_kern_flag & MNTK_SUSPEND_ALL) == 0) + continue; + mtx_unlock(&mountlist_mtx); + MNT_ILOCK(mp); + MPASS((mp->mnt_kern_flag & MNTK_SUSPEND) != 0); + mp->mnt_kern_flag &= ~MNTK_SUSPEND_ALL; + MNT_IUNLOCK(mp); + vfs_write_resume(mp, 0); + mtx_lock(&mountlist_mtx); + vfs_unbusy(mp); + } + mtx_unlock(&mountlist_mtx); +} Modified: stable/12/sys/sys/mount.h ============================================================================== --- stable/12/sys/sys/mount.h Thu Nov 19 08:16:45 2020 (r367835) +++ stable/12/sys/sys/mount.h Thu Nov 19 09:09:19 2020 (r367836) @@ -402,6 +402,7 @@ void __mnt_vnode_markerfree_active(struct vno #define MNTK_USES_BCACHE 0x00004000 /* FS uses the buffer cache. */ #define MNTK_TEXT_REFS 0x00008000 /* Keep use ref for text */ #define MNTK_VMSETSIZE_BUG 0x00010000 +#define MNTK_SUSPEND_ALL 0x00080000 /* Suspended by all-fs suspension */ #define MNTK_NOASYNC 0x00800000 /* disable async */ #define MNTK_UNMOUNT 0x01000000 /* unmount in progress */ #define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */ @@ -972,6 +973,9 @@ vfs_sysctl_t vfs_stdsysctl; void syncer_suspend(void); void syncer_resume(void); + +void suspend_all_fs(void); +void resume_all_fs(void); #else /* !_KERNEL */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202011190909.0AJ99JCX004145>