svn commit: r368075 - head/sys/kern
Konstantin Belousov
kib at FreeBSD.org
Thu Nov 26 18:08:43 UTC 2020
Author: kib
Date: Thu Nov 26 18:08:42 2020
New Revision: 368075
URL: https://svnweb.freebsd.org/changeset/base/368075
Log:
More careful handling of the mount failure.
- VFS_UNMOUNT() requires vn_start_write() around it [*].
- call VFS_PURGE() before unmount.
- do not destroy mp if cleanup unmount did not succeed.
- set MNTK_UNMOUNT, and indicate forced unmount with MNTK_UNMOUNTF
for VFS_UNMOUNT() in cleanup.
PR: 251320 [*]
Reported by: Tong Zhang <ztong0001 at gmail.com>
Reviewed by: markj, mjg
Discussed with: rmacklem
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D27327
Modified:
head/sys/kern/vfs_mount.c
Modified: head/sys/kern/vfs_mount.c
==============================================================================
--- head/sys/kern/vfs_mount.c Thu Nov 26 18:03:24 2020 (r368074)
+++ head/sys/kern/vfs_mount.c Thu Nov 26 18:08:42 2020 (r368075)
@@ -903,6 +903,7 @@ vfs_domount_first(
struct mount *mp;
struct vnode *newdp, *rootvp;
int error, error1;
+ bool unmounted;
ASSERT_VOP_ELOCKED(vp, __func__);
KASSERT((fsflags & MNT_UPDATE) == 0, ("MNT_UPDATE shouldn't be here"));
@@ -964,23 +965,39 @@ vfs_domount_first(
* get. No freeing of cn_pnbuf.
*/
error1 = 0;
+ unmounted = true;
if ((error = VFS_MOUNT(mp)) != 0 ||
(error1 = VFS_STATFS(mp, &mp->mnt_stat)) != 0 ||
(error1 = VFS_ROOT(mp, LK_EXCLUSIVE, &newdp)) != 0) {
rootvp = NULL;
if (error1 != 0) {
- error = error1;
+ MPASS(error == 0);
rootvp = vfs_cache_root_clear(mp);
if (rootvp != NULL) {
vhold(rootvp);
vrele(rootvp);
}
- if ((error1 = VFS_UNMOUNT(mp, 0)) != 0)
- printf("VFS_UNMOUNT returned %d\n", error1);
+ (void)vn_start_write(NULL, &mp, V_WAIT);
+ MNT_ILOCK(mp);
+ mp->mnt_kern_flag |= MNTK_UNMOUNT | MNTK_UNMOUNTF;
+ MNT_IUNLOCK(mp);
+ VFS_PURGE(mp);
+ error = VFS_UNMOUNT(mp, 0);
+ vn_finished_write(mp);
+ if (error != 0) {
+ printf(
+ "failed post-mount (%d): rollback unmount returned %d\n",
+ error1, error);
+ unmounted = false;
+ }
+ error = error1;
}
vfs_unbusy(mp);
mp->mnt_vnodecovered = NULL;
- vfs_mount_destroy(mp);
+ if (unmounted) {
+ /* XXXKIB wait for mnt_lockref drain? */
+ vfs_mount_destroy(mp);
+ }
VI_LOCK(vp);
vp->v_iflag &= ~VI_MOUNT;
VI_UNLOCK(vp);
More information about the svn-src-all
mailing list