Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/msdosfs/msdosfs_vfsops.c
Context not available. | |||||
pmp = VFSTOMSDOSFS(mp); | pmp = VFSTOMSDOSFS(mp); | ||||
if (!(pmp->pm_flags & MSDOSFSMNT_RONLY) && | if (!(pmp->pm_flags & MSDOSFSMNT_RONLY) && | ||||
vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) { | vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) { | ||||
error = VFS_SYNC(mp, MNT_WAIT); | if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0) | ||||
if (error) | return (error); | ||||
error = vfs_write_suspend_umnt(mp); | |||||
if (error != 0) | |||||
return (error); | return (error); | ||||
flags = WRITECLOSE; | flags = WRITECLOSE; | ||||
if (mp->mnt_flag & MNT_FORCE) | if (mp->mnt_flag & MNT_FORCE) | ||||
flags |= FORCECLOSE; | flags |= FORCECLOSE; | ||||
error = vflush(mp, 0, flags, td); | error = vflush(mp, 0, flags, td); | ||||
if (error) | if (error != 0) { | ||||
vfs_write_resume(mp, 0); | |||||
return (error); | return (error); | ||||
} | |||||
/* | /* | ||||
* Now the volume is clean. Mark it so while the | * Now the volume is clean. Mark it so while the | ||||
* device is still rw. | * device is still rw. | ||||
*/ | */ | ||||
error = markvoldirty(pmp, 0); | error = markvoldirty(pmp, 0); | ||||
if (error) { | if (error != 0) { | ||||
vfs_write_resume(mp, 0); | |||||
(void)markvoldirty(pmp, 1); | (void)markvoldirty(pmp, 1); | ||||
return (error); | return (error); | ||||
} | } | ||||
Context not available. | |||||
error = g_access(pmp->pm_cp, 0, -1, 0); | error = g_access(pmp->pm_cp, 0, -1, 0); | ||||
g_topology_unlock(); | g_topology_unlock(); | ||||
if (error) { | if (error) { | ||||
vfs_write_resume(mp, 0); | |||||
(void)markvoldirty(pmp, 1); | (void)markvoldirty(pmp, 1); | ||||
return (error); | return (error); | ||||
} | } | ||||
Context not available. | |||||
MNT_ILOCK(mp); | MNT_ILOCK(mp); | ||||
mp->mnt_flag |= MNT_RDONLY; | mp->mnt_flag |= MNT_RDONLY; | ||||
MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
vfs_write_resume(mp, 0); | |||||
} else if ((pmp->pm_flags & MSDOSFSMNT_RONLY) && | } else if ((pmp->pm_flags & MSDOSFSMNT_RONLY) && | ||||
!vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) { | !vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) { | ||||
/* | /* | ||||
Context not available. | |||||
{ | { | ||||
struct msdosfsmount *pmp; | struct msdosfsmount *pmp; | ||||
int error, flags; | int error, flags; | ||||
bool susp; | |||||
error = flags = 0; | error = flags = 0; | ||||
pmp = VFSTOMSDOSFS(mp); | pmp = VFSTOMSDOSFS(mp); | ||||
if ((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0) | susp = (pmp->pm_flags & MSDOSFSMNT_RONLY) == 0; | ||||
error = msdosfs_sync(mp, MNT_WAIT); | |||||
if (susp) { | |||||
error = vfs_write_suspend_umnt(mp); | |||||
if (error != 0) | |||||
return (error); | |||||
} | |||||
if ((mntflags & MNT_FORCE) != 0) | if ((mntflags & MNT_FORCE) != 0) | ||||
flags |= FORCECLOSE; | flags |= FORCECLOSE; | ||||
else if (error != 0) | |||||
return (error); | |||||
error = vflush(mp, 0, flags, curthread); | 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); | return (error); | ||||
if ((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0) { | } | ||||
if (susp) { | |||||
error = markvoldirty(pmp, 0); | 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); | (void)markvoldirty(pmp, 1); | ||||
return (error); | return (error); | ||||
} | } | ||||
Context not available. | |||||
BO_UNLOCK(bo); | BO_UNLOCK(bo); | ||||
} | } | ||||
#endif | #endif | ||||
if (susp) | |||||
vfs_write_resume(mp, VR_START_WRITE); | |||||
imp: Why do we need to resume writes if we're unmounting and near the end of that process? Is this a… | |||||
Done Inline ActionsDraining mount point for safe state in vfs_mount_destroy() checks that there is no active writers when mp is destroyed. VFS guarantees that no new consumers can enter mp when VFS_UNMOUNT() is called, so this is a precaution against bugs in this area, and calls to vfs_write_resume() restore invariant that is assumed by the unmount code. kib: Draining mount point for safe state in vfs_mount_destroy() checks that there is no active… | |||||
g_topology_lock(); | g_topology_lock(); | ||||
g_vfs_close(pmp->pm_cp); | g_vfs_close(pmp->pm_cp); | ||||
g_topology_unlock(); | g_topology_unlock(); | ||||
Context not available. |
Why do we need to resume writes if we're unmounting and near the end of that process? Is this a precondition for something else?