svn commit: r367836 - in stable/12/sys: dev/acpica dev/xen/control kern sys

Konstantin Belousov kib at FreeBSD.org
Thu Nov 19 09:09:20 UTC 2020


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 */
 


More information about the svn-src-all mailing list