svn commit: r367895 - head/sys/fs/msdosfs

Konstantin Belousov kib at FreeBSD.org
Fri Nov 20 15:19:31 UTC 2020


Author: kib
Date: Fri Nov 20 15:19:30 2020
New Revision: 367895
URL: https://svnweb.freebsd.org/changeset/base/367895

Log:
  msdosfs: suspend around unmount or remount rw->ro.
  
  This also eliminates unsafe use of VFS_SYNC(MNT_WAIT).
  
  Requested by:	mckusick
  Discussed with:	imp
  Tested by:	pho (previous version)
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks
  Differential revision:	https://reviews.freebsd.org/D27269

Modified:
  head/sys/fs/msdosfs/msdosfs_vfsops.c

Modified: head/sys/fs/msdosfs/msdosfs_vfsops.c
==============================================================================
--- head/sys/fs/msdosfs/msdosfs_vfsops.c	Fri Nov 20 14:45:45 2020	(r367894)
+++ head/sys/fs/msdosfs/msdosfs_vfsops.c	Fri Nov 20 15:19:30 2020	(r367895)
@@ -248,22 +248,28 @@ msdosfs_mount(struct mount *mp)
 		pmp = VFSTOMSDOSFS(mp);
 		if (!(pmp->pm_flags & MSDOSFSMNT_RONLY) &&
 		    vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) {
-			error = VFS_SYNC(mp, MNT_WAIT);
-			if (error)
+			if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
 				return (error);
+			error = vfs_write_suspend_umnt(mp);
+			if (error != 0)
+				return (error);
+
 			flags = WRITECLOSE;
 			if (mp->mnt_flag & MNT_FORCE)
 				flags |= FORCECLOSE;
 			error = vflush(mp, 0, flags, td);
-			if (error)
+			if (error != 0) {
+				vfs_write_resume(mp, 0);
 				return (error);
+			}
 
 			/*
 			 * Now the volume is clean.  Mark it so while the
 			 * device is still rw.
 			 */
 			error = markvoldirty(pmp, 0);
-			if (error) {
+			if (error != 0) {
+				vfs_write_resume(mp, 0);
 				(void)markvoldirty(pmp, 1);
 				return (error);
 			}
@@ -273,6 +279,7 @@ msdosfs_mount(struct mount *mp)
 			error = g_access(pmp->pm_cp, 0, -1, 0);
 			g_topology_unlock();
 			if (error) {
+				vfs_write_resume(mp, 0);
 				(void)markvoldirty(pmp, 1);
 				return (error);
 			}
@@ -286,6 +293,7 @@ msdosfs_mount(struct mount *mp)
 			MNT_ILOCK(mp);
 			mp->mnt_flag |= MNT_RDONLY;
 			MNT_IUNLOCK(mp);
+			vfs_write_resume(mp, 0);
 		} else if ((pmp->pm_flags & MSDOSFSMNT_RONLY) &&
 		    !vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) {
 			/*
@@ -749,21 +757,31 @@ msdosfs_unmount(struct mount *mp, int mntflags)
 {
 	struct msdosfsmount *pmp;
 	int error, flags;
+	bool susp;
 
 	error = flags = 0;
 	pmp = VFSTOMSDOSFS(mp);
-	if ((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0)
-		error = msdosfs_sync(mp, MNT_WAIT);
+	susp = (pmp->pm_flags & MSDOSFSMNT_RONLY) == 0;
+
+	if (susp) {
+		error = vfs_write_suspend_umnt(mp);
+		if (error != 0)
+			return (error);
+	}
+
 	if ((mntflags & MNT_FORCE) != 0)
 		flags |= FORCECLOSE;
-	else if (error != 0)
-		return (error);
 	error = vflush(mp, 0, flags, curthread);
-	if (error != 0 && error != ENXIO)
+	if (error != 0 && error != ENXIO) {
+		if (susp)
+			vfs_write_resume(mp, VR_START_WRITE);
 		return (error);
-	if ((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0) {
+	}
+	if (susp) {
 		error = markvoldirty(pmp, 0);
-		if (error && error != ENXIO) {
+		if (error != 0 && error != ENXIO) {
+			if (susp)
+				vfs_write_resume(mp, VR_START_WRITE);
 			(void)markvoldirty(pmp, 1);
 			return (error);
 		}
@@ -800,6 +818,9 @@ msdosfs_unmount(struct mount *mp, int mntflags)
 		BO_UNLOCK(bo);
 	}
 #endif
+	if (susp)
+		vfs_write_resume(mp, VR_START_WRITE);
+
 	g_topology_lock();
 	g_vfs_close(pmp->pm_cp);
 	g_topology_unlock();


More information about the svn-src-all mailing list