From owner-dev-commits-src-all@freebsd.org Wed Feb 24 07:57:03 2021 Return-Path: Delivered-To: dev-commits-src-all@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 46B7A553664; Wed, 24 Feb 2021 07:57:03 +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 4DlpCy1KKDz4Yc3; Wed, 24 Feb 2021 07:57:02 +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 C2E5928E10; Wed, 24 Feb 2021 07:57:01 +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 11O7v1qb045798; Wed, 24 Feb 2021 07:57:01 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 11O7v1u1045797; Wed, 24 Feb 2021 07:57:01 GMT (envelope-from git) Date: Wed, 24 Feb 2021 07:57:01 GMT Message-Id: <202102240757.11O7v1u1045797@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: 5e198e7646a2 - main - ffs_close_ea: do not relock vnode under lock_ea 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/main X-Git-Reftype: branch X-Git-Commit: 5e198e7646a27412c0541719f7bf1bbc0bd89223 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Feb 2021 07:57:09 -0000 The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=5e198e7646a27412c0541719f7bf1bbc0bd89223 commit 5e198e7646a27412c0541719f7bf1bbc0bd89223 Author: Konstantin Belousov AuthorDate: 2021-02-21 10:10:06 +0000 Commit: Konstantin Belousov CommitDate: 2021-02-24 07:55:04 +0000 ffs_close_ea: do not relock vnode under lock_ea ffs_lock_ea is after the vnode lock, so vnode must not be relocked under lock_ea. Move ffs_truncate() call in ffs_close_ea() after the lock_ea is dropped, and only truncate to length zero, since this is the only mode supported by ffs_truncate() for EAs. Previously code did truncation and then write. Zero the part of the ext area that is unused, if truncation is due but not done because ea area is not zero-length. Reviewed by: mckusick Tested by: pho MFC after: 1 week Sponsored by: The FreeBSD Foundation --- sys/ufs/ffs/ffs_vnops.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 4e574f85c9e4..9be46951c04e 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -1422,9 +1422,10 @@ ffs_close_ea(struct vnode *vp, int commit, struct ucred *cred, struct thread *td { struct inode *ip; struct uio luio; - struct iovec liovec; + struct iovec *liovec; struct ufs2_dinode *dp; - int error; + size_t ea_len, tlen; + int error, i, lcnt; ip = VTOI(vp); @@ -1439,18 +1440,31 @@ ffs_close_ea(struct vnode *vp, int commit, struct ucred *cred, struct thread *td ASSERT_VOP_ELOCKED(vp, "ffs_close_ea commit"); if (cred == NOCRED) cred = vp->v_mount->mnt_cred; - liovec.iov_base = ip->i_ea_area; - liovec.iov_len = ip->i_ea_len; - luio.uio_iov = &liovec; - luio.uio_iovcnt = 1; + + ea_len = MAX(ip->i_ea_len, dp->di_extsize); + for (lcnt = 1, tlen = ea_len - ip->i_ea_len; tlen > 0;) { + tlen -= MIN(ZERO_REGION_SIZE, tlen); + lcnt++; + } + + liovec = __builtin_alloca(lcnt * sizeof(struct iovec)); + luio.uio_iovcnt = lcnt; + + liovec[0].iov_base = ip->i_ea_area; + liovec[0].iov_len = ip->i_ea_len; + for (i = 1, tlen = ea_len; i < lcnt; i++) { + liovec[i].iov_base = __DECONST(void *, zero_region); + liovec[i].iov_len = MIN(ZERO_REGION_SIZE, tlen); + tlen -= liovec[i].iov_len; + } + MPASS(tlen == ip->i_ea_len); + + luio.uio_iov = liovec; luio.uio_offset = 0; - luio.uio_resid = ip->i_ea_len; + luio.uio_resid = ea_len; luio.uio_segflg = UIO_SYSSPACE; luio.uio_rw = UIO_WRITE; luio.uio_td = td; - /* XXX: I'm not happy about truncating to zero size */ - if (ip->i_ea_len < dp->di_extsize) - error = ffs_truncate(vp, 0, IO_EXT, cred); error = ffs_extwrite(vp, &luio, IO_EXT | IO_SYNC, cred); } if (--ip->i_ea_refs == 0) { @@ -1460,6 +1474,9 @@ ffs_close_ea(struct vnode *vp, int commit, struct ucred *cred, struct thread *td ip->i_ea_error = 0; } ffs_unlock_ea(vp); + + if (commit && error == 0 && ip->i_ea_len == 0) + ffs_truncate(vp, 0, IO_EXT, cred); return (error); }