From owner-svn-src-head@freebsd.org Fri Dec 27 16:43:34 2019 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 B23961C88B3; Fri, 27 Dec 2019 16:43:34 +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) server-signature RSA-PSS (4096 bits) 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 47kt1f46sGz4Hly; Fri, 27 Dec 2019 16:43:34 +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 88D6E1BB7D; Fri, 27 Dec 2019 16:43:34 +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 xBRGhYLc005394; Fri, 27 Dec 2019 16:43:34 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xBRGhY4q005393; Fri, 27 Dec 2019 16:43:34 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201912271643.xBRGhY4q005393@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Fri, 27 Dec 2019 16:43:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r356126 - head/sys/ufs/ffs X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: head/sys/ufs/ffs X-SVN-Commit-Revision: 356126 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.29 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: Fri, 27 Dec 2019 16:43:34 -0000 Author: kib Date: Fri Dec 27 16:43:34 2019 New Revision: 356126 URL: https://svnweb.freebsd.org/changeset/base/356126 Log: ufs: do not leave non-reclaimed vnodes with zero i_mode around. After a recent change, vput() relocks even the exclusively locked vnode before inactivating it. Before that, UFS could safely instantiate a vnode for cleared inode, then the last vput() after ffs_vgetf() noted that ip->i_mode == 0 and recycled. Now, it is possible for other threads to note the half-constructed vnode, e.g. to insert it into hash, which makes other threads to use it despite mode is zero, before inactivation and reclaim. Handle the found cases in SU code, by explicitly doing reclaim. Assert that other places get fully constructed inode from ffs_vgetf(), which cannot be cleared before dependencies are resolved. Reported and tested by: pho Reviewed by: mckusick Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/sys/ufs/ffs/ffs_softdep.c Modified: head/sys/ufs/ffs/ffs_softdep.c ============================================================================== --- head/sys/ufs/ffs/ffs_softdep.c Fri Dec 27 16:28:43 2019 (r356125) +++ head/sys/ufs/ffs/ffs_softdep.c Fri Dec 27 16:43:34 2019 (r356126) @@ -8052,7 +8052,9 @@ handle_complete_freeblocks(freeblks, flags) flags, &vp, FFSV_FORCEINSMQ) != 0) return (EBUSY); ip = VTOI(vp); - if (DIP(ip, i_modrev) == freeblks->fb_modrev) { + if (ip->i_mode == 0) { + vgone(vp); + } else if (DIP(ip, i_modrev) == freeblks->fb_modrev) { DIP_SET(ip, i_blocks, DIP(ip, i_blocks) - spare); ip->i_flag |= IN_CHANGE; /* @@ -9835,6 +9837,7 @@ handle_workitem_remove(dirrem, flags) if (ffs_vgetf(mp, oldinum, flags, &vp, FFSV_FORCEINSMQ) != 0) return (EBUSY); ip = VTOI(vp); + MPASS(ip->i_mode != 0); ACQUIRE_LOCK(ump); if ((inodedep_lookup(mp, oldinum, 0, &inodedep)) == 0) panic("handle_workitem_remove: lost inodedep"); @@ -12530,6 +12533,7 @@ restart: VOP_UNLOCK(vp, 0); error = ffs_vgetf(mp, parentino, LK_EXCLUSIVE, &pvp, FFSV_FORCEINSMQ); + MPASS(VTOI(pvp)->i_mode != 0); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); if (VN_IS_DOOMED(vp)) { if (error == 0) @@ -13172,6 +13176,7 @@ restart: if ((error = ffs_vgetf(mp, inum, LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ))) break; + MPASS(VTOI(vp)->i_mode != 0); error = flush_newblk_dep(vp, mp, 0); /* * If we still have the dependency we might need to @@ -13236,6 +13241,7 @@ retry: if ((error = ffs_vgetf(mp, inum, LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ))) break; + MPASS(VTOI(vp)->i_mode != 0); error = ffs_update(vp, 1); vput(vp); if (error) @@ -13830,6 +13836,7 @@ clear_remove(mp) softdep_error("clear_remove: vget", error); goto finish_write; } + MPASS(VTOI(vp)->i_mode != 0); if ((error = ffs_syncvnode(vp, MNT_NOWAIT, 0))) softdep_error("clear_remove: fsync", error); bo = &vp->v_bufobj; @@ -13911,7 +13918,9 @@ clear_inodedeps(mp) return; } vfs_unbusy(mp); - if (ino == lastino) { + if (VTOI(vp)->i_mode == 0) { + vgone(vp); + } else if (ino == lastino) { if ((error = ffs_syncvnode(vp, MNT_WAIT, 0))) softdep_error("clear_inodedeps: fsync1", error); } else {