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