In dounmount(), only call checkdirs() prior to VFS_UNMOUNT() in the

forced unmount case. Otherwise, a file system that is referenced
only by process fd_cdir/fd_rdir references to the file system root
vnode will be successfully unmounted without the MNT_FORCE flag.

The previous behaviour was not compatible with the unmount semantics
required by amd(8), so file systems could be unexpectedly unmounted
while there were still references to the file system root directory.

Reported by:	Erez Zadok <ezk@cs.sunysb.edu>
Approved by:	re (scottl)
This commit is contained in:
Ian Dowse 2003-11-30 23:30:09 +00:00
parent 28c6f1ae42
commit 25cb5d7a6b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=123075

View File

@ -1110,8 +1110,12 @@ dounmount(mp, flags, td)
cache_purgevfs(mp); /* remove cache entries for this file sys */
if (mp->mnt_syncer != NULL)
vrele(mp->mnt_syncer);
/* Move process cdir/rdir refs on fs root to underlying vnode. */
if (VFS_ROOT(mp, &fsrootvp) == 0) {
/*
* For forced unmounts, move process cdir/rdir refs on the fs root
* vnode to the covered vnode. For non-forced unmounts we want
* such references to cause an EBUSY error.
*/
if ((flags & MNT_FORCE) && VFS_ROOT(mp, &fsrootvp) == 0) {
if (mp->mnt_vnodecovered != NULL)
checkdirs(fsrootvp, mp->mnt_vnodecovered);
if (fsrootvp == rootvnode) {
@ -1128,7 +1132,7 @@ dounmount(mp, flags, td)
vn_finished_write(mp);
if (error) {
/* Undo cdir/rdir and rootvnode changes made above. */
if (VFS_ROOT(mp, &fsrootvp) == 0) {
if ((flags & MNT_FORCE) && VFS_ROOT(mp, &fsrootvp) == 0) {
if (mp->mnt_vnodecovered != NULL)
checkdirs(mp->mnt_vnodecovered, fsrootvp);
if (rootvnode == NULL) {