erofs: fix metabuf leak in inode xattr initialization
commitmasterbb88e8da00("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:bb88e8da00("erofs: use meta buffers for xattr operations") Signed-off-by: Jia Zhu <zhujia.zj@bytedance.com> Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com> Fixes:bb88e8da00("erofs: use meta buffers for xattr operations") Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
parent
649932fc38
commit
79b09c54c6
|
|
@ -89,13 +89,11 @@ static int erofs_init_inode_xattrs(struct inode *inode)
|
||||||
vi->xattr_isize - sizeof(struct erofs_xattr_ibody_header)) {
|
vi->xattr_isize - sizeof(struct erofs_xattr_ibody_header)) {
|
||||||
erofs_err(sb, "invalid h_shared_count %u @ nid %llu",
|
erofs_err(sb, "invalid h_shared_count %u @ nid %llu",
|
||||||
vi->xattr_shared_count, vi->nid);
|
vi->xattr_shared_count, vi->nid);
|
||||||
erofs_put_metabuf(&buf);
|
|
||||||
ret = -EFSCORRUPTED;
|
ret = -EFSCORRUPTED;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
vi->xattr_shared_xattrs = kmalloc_objs(uint, vi->xattr_shared_count);
|
vi->xattr_shared_xattrs = kmalloc_objs(uint, vi->xattr_shared_count);
|
||||||
if (!vi->xattr_shared_xattrs) {
|
if (!vi->xattr_shared_xattrs) {
|
||||||
erofs_put_metabuf(&buf);
|
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
@ -112,12 +110,12 @@ static int erofs_init_inode_xattrs(struct inode *inode)
|
||||||
}
|
}
|
||||||
vi->xattr_shared_xattrs[i] = le32_to_cpu(*xattr_id);
|
vi->xattr_shared_xattrs[i] = le32_to_cpu(*xattr_id);
|
||||||
}
|
}
|
||||||
erofs_put_metabuf(&buf);
|
|
||||||
|
|
||||||
/* paired with smp_mb() at the beginning of the function. */
|
/* paired with smp_mb() at the beginning of the function. */
|
||||||
smp_mb();
|
smp_mb();
|
||||||
set_bit(EROFS_I_EA_INITED_BIT, &vi->flags);
|
set_bit(EROFS_I_EA_INITED_BIT, &vi->flags);
|
||||||
out_unlock:
|
out_unlock:
|
||||||
|
erofs_put_metabuf(&buf);
|
||||||
clear_and_wake_up_bit(EROFS_I_BL_XATTR_BIT, &vi->flags);
|
clear_and_wake_up_bit(EROFS_I_BL_XATTR_BIT, &vi->flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue