git: b287d46c385b - releng/13.0 - ffs_close_ea: do not relock vnode under lock_ea
Konstantin Belousov
kib at FreeBSD.org
Thu Feb 25 20:52:47 UTC 2021
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 at FreeBSD.org>
AuthorDate: 2021-02-21 10:10:06 +0000
Commit: Konstantin Belousov <kib at 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);
}
More information about the dev-commits-src-all
mailing list