From owner-svn-src-head@freebsd.org Thu Nov 26 18:08:43 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 221EE46AAFB; Thu, 26 Nov 2020 18:08:43 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Chm3H0T6nz4qGk; Thu, 26 Nov 2020 18:08:43 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 02CA227891; Thu, 26 Nov 2020 18:08:43 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0AQI8go3031579; Thu, 26 Nov 2020 18:08:42 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0AQI8gZH031578; Thu, 26 Nov 2020 18:08:42 GMT (envelope-from kib@FreeBSD.org) Message-Id: <202011261808.0AQI8gZH031578@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 26 Nov 2020 18:08:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r368075 - head/sys/kern X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: head/sys/kern X-SVN-Commit-Revision: 368075 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Nov 2020 18:08:43 -0000 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 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);