Date: Thu, 26 Nov 2020 18:08:42 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r368075 - head/sys/kern Message-ID: <202011261808.0AQI8gZH031578@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202011261808.0AQI8gZH031578>