Hi Xiang,
On 2021/2/9 21:06, Gao Xiang via Linux-erofs wrote:
From: Gao Xiang hsiangkao@redhat.com
Currently, although set_bit() & test_bit() pairs are used as a fast- path for initialized configurations. However, these atomic ops are actually relaxed forms. Instead, load-acquire & store-release form is needed to make sure uninitialized fields won't be observed in advance here (yet no such corresponding bitops so use full barriers instead.)
Fixes: 62dc45979f3f ("staging: erofs: fix race of initializing xattrs of a inode at the same time") Fixes: 152a333a5895 ("staging: erofs: add compacted compression indexes support") Cc: stable@vger.kernel.org # 5.3+ Reported-by: Huang Jianan huangjianan@oppo.com Signed-off-by: Gao Xiang hsiangkao@redhat.com
fs/erofs/xattr.c | 10 +++++++++- fs/erofs/zmap.c | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c index 5bde77d70852..47314a26767a 100644 --- a/fs/erofs/xattr.c +++ b/fs/erofs/xattr.c @@ -48,8 +48,14 @@ static int init_inode_xattrs(struct inode *inode) int ret = 0; /* the most case is that xattrs of this inode are initialized. */
- if (test_bit(EROFS_I_EA_INITED_BIT, &vi->flags))
- if (test_bit(EROFS_I_EA_INITED_BIT, &vi->flags)) {
/*
* paired with smp_mb() at the end of the function to ensure
* fields will only be observed after the bit is set.
*/
smp_mb();
I can understand below usage, since w/o smp_mb(), xattr initialization could be done after set_bit(EROFS_I_EA_INITED_BIT), then other apps could see out-of-update xattr info after that bit check.
So what out-of-order execution do we need to avoid by adding above barrier?
Thanks,
- /* paired with smp_mb() at the beginning of the function. */
- smp_mb(); set_bit(EROFS_I_EA_INITED_BIT, &vi->flags);