6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jia Zhu [ Upstream commit 79b09c54c6563df9846ca3094bcfd72082c3e1d7 ] commit bb88e8da0025 ("erofs: use meta buffers for xattr operations") converted xattr operations to use on-stack erofs_buf instances. erofs_init_inode_xattrs() uses such a metabuf while reading the inline xattr header and shared xattr id array. Some error paths after erofs_read_metabuf() leave through out_unlock without dropping the metabuf, so the folio reference can leak. Consolidate the cleanup at out_unlock. erofs_put_metabuf() is a no-op if no folio has been acquired, and this keeps all paths after taking EROFS_I_BL_XATTR_BIT covered by a single cleanup site. Fixes: bb88e8da0025 ("erofs: use meta buffers for xattr operations") Signed-off-by: Jia Zhu Reviewed-by: Gao Xiang Fixes: bb88e8da0025 ("erofs: use meta buffers for xattr operations") Signed-off-by: Gao Xiang Signed-off-by: Sasha Levin --- fs/erofs/xattr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c index 396536d9a8621..59de3253e4665 100644 --- a/fs/erofs/xattr.c +++ b/fs/erofs/xattr.c @@ -34,6 +34,8 @@ static int erofs_init_inode_xattrs(struct inode *inode) struct super_block *sb = inode->i_sb; int ret = 0; + it.buf = __EROFS_BUF_INITIALIZER; + /* the most case is that xattrs of this inode are initialized. */ if (test_bit(EROFS_I_EA_INITED_BIT, &vi->flags)) { /* @@ -76,7 +78,6 @@ static int erofs_init_inode_xattrs(struct inode *inode) goto out_unlock; } - it.buf = __EROFS_BUF_INITIALIZER; ret = erofs_init_metabuf(&it.buf, sb, erofs_inode_in_metabox(inode)); if (ret) goto out_unlock; @@ -95,7 +96,6 @@ static int erofs_init_inode_xattrs(struct inode *inode) vi->xattr_shared_xattrs = kmalloc_array(vi->xattr_shared_count, sizeof(uint), GFP_KERNEL); if (!vi->xattr_shared_xattrs) { - erofs_put_metabuf(&it.buf); ret = -ENOMEM; goto out_unlock; } @@ -114,13 +114,13 @@ static int erofs_init_inode_xattrs(struct inode *inode) vi->xattr_shared_xattrs[i] = le32_to_cpu(*(__le32 *)it.kaddr); it.pos += sizeof(__le32); } - erofs_put_metabuf(&it.buf); /* paired with smp_mb() at the beginning of the function. */ smp_mb(); set_bit(EROFS_I_EA_INITED_BIT, &vi->flags); out_unlock: + erofs_put_metabuf(&it.buf); clear_and_wake_up_bit(EROFS_I_BL_XATTR_BIT, &vi->flags); return ret; } -- 2.53.0