From nobody Mon May 25 01:17:55 2026 Received: from va-1-114.ptr.blmpb.com (va-1-114.ptr.blmpb.com [209.127.230.114]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4EC4E314D2D for ; Wed, 20 May 2026 03:45:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.127.230.114 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779248754; cv=none; b=Luu+jXHMh4FWnXRvDzpwVVASyQyFfs9e+nR73P6JCSxRBK/EPB9ZfroQ58rRlZO8GM58tlWgnGkGdYAUtWuJI72ZFJuTPQgypyDwxZmXTYputo6lqNoDjJYCyKjs2/qviK/f2uSTBbLsHPAAymBJNVFjsQsGKsCgSHYd23VRgos= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779248754; c=relaxed/simple; bh=ehDKgfDdSRPoytqTXlPOeo2qahcOzmX7J//M42pcZEg=; h=Content-Type:Cc:To:Subject:Date:Message-Id:From:Mime-Version; b=UErmcoH77awE9Ae8G2dpfZy6rpwy007YfcnDlBmTVAI3SR3t0zeeU33imwX/354tO3H0kr5fkLcynB1XcIFUNvNVlJVYBM4IsIu0MOJJct+KNi4lZ05OQsz5iYuzhUSfNBPu45smooAq4EQIudJ4DRL/Q5jprnS4ubpf5lMEAfs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=bytedance.com; spf=pass smtp.mailfrom=bytedance.com; dkim=pass (2048-bit key) header.d=bytedance.com header.i=@bytedance.com header.b=qcURkZT6; arc=none smtp.client-ip=209.127.230.114 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=bytedance.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bytedance.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bytedance.com header.i=@bytedance.com header.b="qcURkZT6" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=2212171451; d=bytedance.com; t=1779248741; h=from:subject: mime-version:from:date:message-id:subject:to:cc:reply-to:content-type: mime-version:in-reply-to:message-id; bh=mspc1aUu6CgWqs54mQCmP4k4Liy2LtNRdjCy1C379GM=; b=qcURkZT6qvTt91eJmHS2T0Jevgc8irO+e3CUo058XIwhEjVklqdNTZo9WZ6cC2U6N79c81 ti9o4/RPYi3qGalxVnBzsD4BAS509f3kGCGbrY1tq6Jb6jwIZT2Q5Ai+OixjnIucmKwAPD Lc2TwWYhpxNH8hJF7/3oh8G1+Ox/XZ8YFGRS13aFNfbbXGOG+gyX8ki+8IAFXaYsuBEGdn U+r1aZ3vqNCt1iQQXh+H+eCw5k9YvqPiqHNui2/qX+2kxxAp38Y2TYDHLRDueiXrjp1UUS ZPRWRCc7p6aR713VWnVextLq1Ck6muausq9OQqWGoMfwim4JViitWRHZOQxtBg== Content-Transfer-Encoding: quoted-printable Cc: , , "Yue Hu" , "Jeffle Xu" , "Sandeep Dhavale" , "Hongbo Li" , "Chunhai Guo" , "Gao Xiang" , "Jia Zhu" X-Original-From: Jia Zhu X-Lms-Return-Path: To: "Gao Xiang" , "Chao Yu" Subject: [PATCH] erofs: reuse xattr metabuf across init and iterators Date: Wed, 20 May 2026 11:45:32 +0800 Message-Id: <20260520034532.42557-1-zhujia.zj@bytedance.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) From: "Jia Zhu" Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" erofs_init_inode_xattrs() used a local metabuf to read the inline xattr header and shared xattr ids. getxattr and listxattr then initialized a separate iterator metabuf for the following inline/shared xattr walk. Pass the iterator metabuf into erofs_init_inode_xattrs() so initialization and the inline iterator path share the same metabuf lifetime. The getxattr and listxattr callers now use a single cleanup exit for their iterator metabuf. Drop and reinitialize the metabuf before switching from inline xattrs to the shared xattr metadata area, since that path may use a different mapping. Signed-off-by: Jia Zhu --- fs/erofs/xattr.c | 76 ++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c index df7ea019526d7..f7eb7431b0b81 100644 --- a/fs/erofs/xattr.c +++ b/fs/erofs/xattr.c @@ -27,9 +27,8 @@ struct erofs_xattr_iter { =20 static const char *erofs_xattr_prefix(unsigned int idx, struct dentry *den= try); =20 -static int erofs_init_inode_xattrs(struct inode *inode) +static int erofs_init_inode_xattrs(struct erofs_buf *buf, struct inode *in= ode) { - struct erofs_buf buf =3D __EROFS_BUF_INITIALIZER; struct erofs_inode *vi =3D EROFS_I(inode); struct super_block *sb =3D inode->i_sb; const struct erofs_xattr_ibody_header *ih; @@ -78,7 +77,7 @@ static int erofs_init_inode_xattrs(struct inode *inode) } =20 pos =3D erofs_iloc(inode) + vi->inode_isize; - ih =3D erofs_read_metabuf(&buf, sb, pos, erofs_inode_in_metabox(inode)); + ih =3D erofs_read_metabuf(buf, sb, pos, erofs_inode_in_metabox(inode)); if (IS_ERR(ih)) { ret =3D PTR_ERR(ih); goto out_unlock; @@ -101,7 +100,7 @@ static int erofs_init_inode_xattrs(struct inode *inode) /* skip the ibody header and read the shared xattr array */ pos +=3D sizeof(struct erofs_xattr_ibody_header); for (i =3D 0; i < vi->xattr_shared_count; ++i) { - xattr_id =3D erofs_bread(&buf, pos + i * sizeof(__le32), true); + xattr_id =3D erofs_bread(buf, pos + i * sizeof(__le32), true); if (IS_ERR(xattr_id)) { kfree(vi->xattr_shared_xattrs); vi->xattr_shared_xattrs =3D NULL; @@ -115,7 +114,6 @@ static int erofs_init_inode_xattrs(struct inode *inode) smp_mb(); set_bit(EROFS_I_EA_INITED_BIT, &vi->flags); out_unlock: - erofs_put_metabuf(&buf); clear_and_wake_up_bit(EROFS_I_BL_XATTR_BIT, &vi->flags); return ret; } @@ -337,40 +335,48 @@ static int erofs_getxattr(struct inode *inode, int in= dex, const char *name, { int ret; unsigned int hashbit; - struct erofs_xattr_iter it; + struct erofs_xattr_iter it =3D { + .sb =3D inode->i_sb, + .buf =3D __EROFS_BUF_INITIALIZER, + .buffer =3D buffer, + .buffer_size =3D buffer_size, + .buffer_ofs =3D 0, + }; struct erofs_inode *vi =3D EROFS_I(inode); struct erofs_sb_info *sbi =3D EROFS_SB(inode->i_sb); =20 if (!name) return -EINVAL; =20 - ret =3D erofs_init_inode_xattrs(inode); + ret =3D erofs_init_inode_xattrs(&it.buf, inode); if (ret) - return ret; + goto out; =20 /* reserved flag is non-zero if there's any change of on-disk format */ if (erofs_sb_has_xattr_filter(sbi) && !sbi->xattr_filter_reserved) { hashbit =3D xxh32(name, strlen(name), EROFS_XATTR_FILTER_SEED + index); hashbit &=3D EROFS_XATTR_FILTER_BITS - 1; - if (vi->xattr_name_filter & (1U << hashbit)) - return -ENODATA; + if (vi->xattr_name_filter & (1U << hashbit)) { + ret =3D -ENODATA; + goto out; + } } =20 it.index =3D index; it.name =3D QSTR(name); - if (it.name.len > EROFS_NAME_LEN) - return -ERANGE; - - it.sb =3D inode->i_sb; - it.buf =3D __EROFS_BUF_INITIALIZER; - it.buffer =3D buffer; - it.buffer_size =3D buffer_size; - it.buffer_ofs =3D 0; + if (it.name.len > EROFS_NAME_LEN) { + ret =3D -ERANGE; + goto out; + } =20 ret =3D erofs_xattr_iter_inline(&it, inode, true); - if (ret =3D=3D -ENODATA) + if (ret =3D=3D -ENODATA) { + erofs_put_metabuf(&it.buf); + it.buf =3D __EROFS_BUF_INITIALIZER; ret =3D erofs_xattr_iter_shared(&it, inode, true); + } +out: erofs_put_metabuf(&it.buf); return ret ? ret : it.buffer_ofs; } @@ -378,27 +384,33 @@ static int erofs_getxattr(struct inode *inode, int in= dex, const char *name, ssize_t erofs_listxattr(struct dentry *dentry, char *buffer, size_t buffer= _size) { int ret; - struct erofs_xattr_iter it; + struct erofs_xattr_iter it =3D { + .sb =3D dentry->d_sb, + .buf =3D __EROFS_BUF_INITIALIZER, + .dentry =3D dentry, + .buffer =3D buffer, + .buffer_size =3D buffer_size, + .buffer_ofs =3D 0, + }; struct inode *inode =3D d_inode(dentry); =20 - ret =3D erofs_init_inode_xattrs(inode); - if (ret =3D=3D -ENODATA) - return 0; + ret =3D erofs_init_inode_xattrs(&it.buf, inode); + if (ret =3D=3D -ENODATA) { + ret =3D 0; + goto out; + } if (ret) - return ret; - - it.sb =3D dentry->d_sb; - it.buf =3D __EROFS_BUF_INITIALIZER; - it.dentry =3D dentry; - it.buffer =3D buffer; - it.buffer_size =3D buffer_size; - it.buffer_ofs =3D 0; + goto out; =20 ret =3D erofs_xattr_iter_inline(&it, inode, false); - if (!ret || ret =3D=3D -ENODATA) + if (!ret || ret =3D=3D -ENODATA) { + erofs_put_metabuf(&it.buf); + it.buf =3D __EROFS_BUF_INITIALIZER; ret =3D erofs_xattr_iter_shared(&it, inode, false); + } if (ret =3D=3D -ENODATA) ret =3D 0; +out: erofs_put_metabuf(&it.buf); return ret ? ret : it.buffer_ofs; } --=20 2.39.5 (Apple Git-154)