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
This commit is contained in:
parent
fc2747e5ed
commit
f23271115b
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user