From owner-dev-commits-src-branches@freebsd.org Thu Feb 25 20:52:28 2021 Return-Path: Delivered-To: dev-commits-src-branches@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 EA03556FB52; Thu, 25 Feb 2021 20:52:28 +0000 (UTC) (envelope-from git@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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DmlND0Kd2z3PCy; Thu, 25 Feb 2021 20:52:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 38FF81E5A9; Thu, 25 Feb 2021 20:52:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 11PKqOa3079342; Thu, 25 Feb 2021 20:52:24 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 11PKqOsa079341; Thu, 25 Feb 2021 20:52:24 GMT (envelope-from git) Date: Thu, 25 Feb 2021 20:52:24 GMT Message-Id: <202102252052.11PKqOsa079341@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: b62d17802dcf - releng/13.0 - ufs_direnter: move directory truncation to ffs_vput_pair(). MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/releng/13.0 X-Git-Reftype: branch X-Git-Commit: b62d17802dcf9b589b6572a010e1a65820117155 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Feb 2021 20:52:29 -0000 The branch releng/13.0 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=b62d17802dcf9b589b6572a010e1a65820117155 commit b62d17802dcf9b589b6572a010e1a65820117155 Author: Konstantin Belousov AuthorDate: 2021-01-27 20:34:14 +0000 Commit: Konstantin Belousov CommitDate: 2021-02-25 20:49:09 +0000 ufs_direnter: move directory truncation to ffs_vput_pair(). Approved by: re (delphij, gjb) (cherry picked from commit 74a3652f832f4ed0f1ad9f7eb60d70013b478e1a) --- sys/ufs/ffs/ffs_vnops.c | 44 ++++++++++++++++++++++++++++++++++++++------ sys/ufs/ufs/inode.h | 2 ++ sys/ufs/ufs/ufs_lookup.c | 25 ++++++------------------- 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 2ac67adad5f2..dd0f1ba6b81d 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$"); #include "opt_directio.h" #include "opt_ffs.h" +#include "opt_ufs.h" #include #include @@ -99,6 +100,10 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#ifdef UFS_DIRHASH +#include +#endif #include #include @@ -1929,6 +1934,7 @@ ffs_vput_pair(struct vop_vput_pair_args *ap) struct inode *dp, *ip; ino_t ip_ino; u_int64_t ip_gen; + off_t old_size; int error, vp_locked; dvp = ap->a_dvp; @@ -1936,14 +1942,14 @@ ffs_vput_pair(struct vop_vput_pair_args *ap) vpp = ap->a_vpp; vp = vpp != NULL ? *vpp : NULL; - if ((dp->i_flag & IN_NEEDSYNC) == 0) { + if ((dp->i_flag & (IN_NEEDSYNC | IN_ENDOFF)) == 0) { vput(dvp); if (vp != NULL && ap->a_unlock_vp) vput(vp); return (0); } - mp = NULL; + mp = dvp->v_mount; if (vp != NULL) { if (ap->a_unlock_vp) { vput(vp); @@ -1953,14 +1959,40 @@ ffs_vput_pair(struct vop_vput_pair_args *ap) ip = VTOI(vp); ip_ino = ip->i_number; ip_gen = ip->i_gen; - mp = vp->v_mount; VOP_UNLOCK(vp); } } - do { - error = ffs_syncvnode(dvp, MNT_WAIT, 0); - } while (error == ERELOOKUP); + /* + * If compaction or fsync was requested do it in ffs_vput_pair() + * now that other locks are no longer held. + */ + if ((dp->i_flag & IN_ENDOFF) != 0) { + dp->i_flag &= ~IN_ENDOFF; + if (I_ENDOFF(dp) != 0 && I_ENDOFF(dp) < dp->i_size) { + old_size = dp->i_size; + error = UFS_TRUNCATE(dvp, (off_t)I_ENDOFF(dp), + IO_NORMAL | (DOINGASYNC(dvp) ? 0 : IO_SYNC), + curthread->td_ucred); + if (error != 0 && error != ERELOOKUP) { + if (!ffs_fsfail_cleanup(VFSTOUFS(mp), error)) { + vn_printf(dvp, + "IN_ENDOFF: failed to truncate, " + "error %d\n", error); + } +#ifdef UFS_DIRHASH + ufsdirhash_free(dp); +#endif + } + } + SET_I_ENDOFF(dp, 0); + } + if ((dp->i_flag & IN_NEEDSYNC) != 0) { + do { + error = ffs_syncvnode(dvp, MNT_WAIT, 0); + } while (error == ERELOOKUP); + } + vput(dvp); if (vp == NULL || ap->a_unlock_vp) diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h index 16db8d6d5cea..4515dcbed401 100644 --- a/sys/ufs/ufs/inode.h +++ b/sys/ufs/ufs/inode.h @@ -152,6 +152,8 @@ struct inode { #define IN_IBLKDATA 0x0800 /* datasync requires inode block update */ #define IN_SIZEMOD 0x1000 /* Inode size has been modified */ +#define IN_ENDOFF 0x2000 /* Free space at the end of directory, + try to truncate when possible */ #define PRINT_INODE_FLAGS "\20\20b16\17b15\16b14\15sizemod" \ "\14iblkdata\13is_ufs2\12truncated\11ea_lockwait\10ea_locked" \ diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index e614f189a623..3036bce81caf 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -1112,27 +1112,14 @@ ufs_direnter(dvp, tvp, dirp, cnp, newdirbp, isrename) } } UFS_INODE_SET_FLAG(dp, IN_CHANGE | IN_UPDATE); + /* - * If all went well, and the directory can be shortened, proceed - * with the truncation. Note that we have to unlock the inode for - * the entry that we just entered, as the truncation may need to - * lock other inodes which can lead to deadlock if we also hold a - * lock on the newly entered node. + * If all went well, and the directory can be shortened, mark directory inode + * with the truncation request right before unlock. */ - if (isrename == 0 && error == 0 && - I_ENDOFF(dp) != 0 && I_ENDOFF(dp) < dp->i_size) { - if (tvp != NULL) - VOP_UNLOCK(tvp); - error = UFS_TRUNCATE(dvp, (off_t)I_ENDOFF(dp), - IO_NORMAL | (DOINGASYNC(dvp) ? 0 : IO_SYNC), cr); - if (error != 0) - vn_printf(dvp, - "ufs_direnter: failed to truncate, error %d\n", - error); - error = 0; - if (tvp != NULL) - vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY); - } + if (isrename == 0 && error == 0) + UFS_INODE_SET_FLAG(dp, IN_ENDOFF); + return (error); }