The branch stable/13 has been updated by kib:

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

commit e2827f8a13451f9f6409d111b40fcf6c83b119c5
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2021-02-21 10:10:06 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2021-02-25 12:55:18 +0000

    ffs_close_ea: do not relock vnode under lock_ea
    
    (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);
 }
 
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to