Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Feb 2021 20:52:40 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: b287d46c385b - releng/13.0 - ffs_close_ea: do not relock vnode under lock_ea
Message-ID:  <202102252052.11PKqeD6079633@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch releng/13.0 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=b287d46c385be71440693d3c0d8f4e098dee1207

commit b287d46c385be71440693d3c0d8f4e098dee1207
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-02-21 10:10:06 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-02-25 20:50:52 +0000

    ffs_close_ea: do not relock vnode under lock_ea
    
    Approved by:    re (delphij, gjb)
    
    (cherry picked from commit 5e198e7646a27412c0541719f7bf1bbc0bd89223)
---
 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 f9a6a36d178a..64c72f3d3cc4 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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202102252052.11PKqeD6079633>