[xiang-erofs:dev-test] BUILD SUCCESS 0e9a3c4fae5498e86dd11985143c4858a8300705

2021-02-09 Thread kernel test robot
   allyesconfig
h8300allyesconfig
arc defconfig
parisc  defconfig
s390 allyesconfig
s390 allmodconfig
parisc   allyesconfig
s390defconfig
i386 allyesconfig
sparcallyesconfig
sparc   defconfig
i386   tinyconfig
i386defconfig
mips allyesconfig
mips allmodconfig
powerpc  allyesconfig
powerpc  allmodconfig
powerpc   allnoconfig
x86_64   randconfig-a006-20210209
x86_64   randconfig-a001-20210209
x86_64   randconfig-a005-20210209
x86_64   randconfig-a004-20210209
x86_64   randconfig-a002-20210209
x86_64   randconfig-a003-20210209
i386 randconfig-a001-20210209
i386 randconfig-a005-20210209
i386 randconfig-a003-20210209
i386 randconfig-a002-20210209
i386 randconfig-a006-20210209
i386 randconfig-a004-20210209
i386 randconfig-a016-20210209
i386 randconfig-a013-20210209
i386 randconfig-a012-20210209
i386 randconfig-a014-20210209
i386 randconfig-a011-20210209
i386 randconfig-a015-20210209
riscvnommu_k210_defconfig
riscvnommu_virt_defconfig
riscv allnoconfig
riscv   defconfig
riscv  rv32_defconfig
riscvallmodconfig
x86_64   rhel
x86_64   allyesconfig
x86_64rhel-7.6-kselftests
x86_64  defconfig
x86_64   rhel-8.3
x86_64  rhel-8.3-kbuiltin
x86_64  kexec

clang tested configs:
x86_64   randconfig-a013-20210209
x86_64   randconfig-a014-20210209
x86_64   randconfig-a015-20210209
x86_64   randconfig-a012-20210209
x86_64   randconfig-a016-20210209
x86_64   randconfig-a011-20210209

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


Re: [PATCH v2] erofs-utils: fuse: fix random readlink error

2021-02-09 Thread Gao Xiang via Linux-erofs
Hi Weiwen,

On Sat, Jan 30, 2021 at 02:07:47AM +0800, Hu Weiwen wrote:
> readlink should fill a **null-terminated** string in the buffer.
> 
> To achieve this:
> 1) memset(0) for unmapped extents;
> 2) make erofsfuse_read() properly returning the actual bytes read;
> 3) insert a null character if the path is truncated.
> 
> Link: 
> https://lore.kernel.org/r/20210121101233.gc6...@desktop-n4cecto.huww98.cn

Looked into this patch just now...

The Link tag is only used for refering to the patch itself.

> Signed-off-by: Hu Weiwen 
> ---

...

>  
> @@ -91,9 +92,13 @@ static int erofs_read_raw_data(struct erofs_inode *inode, 
> char *buffer,
>  
>   if (!(map.m_flags & EROFS_MAP_MAPPED)) {
>   if (!map.m_llen) {
> + /* reached EOF */
> + memset(buffer + ptr - offset, 0,
> +offset + size - ptr);
>   ptr = offset + size;
>   continue;
>   }
> + memset(buffer + map.m_la - offset, 0, map.m_llen);

There might be some minor issue --- `offset' could be larger than
`map.m_la' if sparse file is supported then.

I made an update version of this to fix these (some cleanup is
included as well), it would be nice of you to take another look at
this as well...

Thanks,
Gao Xiang

>From bfbd8ee056aca57a77034b8723f3f828f806747b Mon Sep 17 00:00:00 2001
From: Hu Weiwen 
Date: Sat, 30 Jan 2021 02:07:47 +0800
Subject: [PATCH v3] erofs-utils: fuse: fix random readlink error

readlink should fill a **null-terminated** string in the buffer [1].

To achieve this:
1) memset(0) for unmapped extents;
2) make erofsfuse_read() properly returning the actual bytes read;
3) insert a null character if the path is truncated.

[1] https://lore.kernel.org/r/20210121101233.gc6...@desktop-n4cecto.huww98.cn
Signed-off-by: Hu Weiwen 
Signed-off-by: Gao Xiang 
---
 fuse/main.c |  8 
 lib/data.c  | 20 
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/fuse/main.c b/fuse/main.c
index c16291272e75..37119ea8728d 100644
--- a/fuse/main.c
+++ b/fuse/main.c
@@ -74,6 +74,10 @@ static int erofsfuse_read(const char *path, char *buffer,
ret = erofs_pread(, buffer, size, offset);
if (ret)
return ret;
+   if (offset + size > vi.i_size)
+   return vi.i_size - offset;
+   if (offset >= vi.i_size)
+   return 0;
return size;
 }
 
@@ -83,6 +87,10 @@ static int erofsfuse_readlink(const char *path, char 
*buffer, size_t size)
 
if (ret < 0)
return ret;
+   DBG_BUGON(ret > size);
+   if (ret == size)
+   buffer[size - 1] = '\0';
+   erofs_dbg("readlink(%s): %s", path, buffer);
return 0;
 }
 
diff --git a/lib/data.c b/lib/data.c
index 3781846743aa..5bc525f19826 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -29,6 +29,7 @@ static int erofs_map_blocks_flatmode(struct erofs_inode 
*inode,
if (offset >= inode->i_size) {
/* leave out-of-bound access unmapped */
map->m_flags = 0;
+   map->m_plen = 0;
goto out;
}
 
@@ -80,6 +81,7 @@ static int erofs_read_raw_data(struct erofs_inode *inode, 
char *buffer,
erofs_off_t ptr = offset;
 
while (ptr < offset + size) {
+   char *const estart = buffer + ptr - offset;
erofs_off_t eend;
 
map.m_la = ptr;
@@ -89,29 +91,30 @@ static int erofs_read_raw_data(struct erofs_inode *inode, 
char *buffer,
 
DBG_BUGON(map.m_plen != map.m_llen);
 
+   /* trim extent */
+   eend = min(offset + size, map.m_la + map.m_llen);
+   DBG_BUGON(ptr < map.m_la);
+
if (!(map.m_flags & EROFS_MAP_MAPPED)) {
if (!map.m_llen) {
+   /* reached EOF */
+   memset(estart, 0, offset + size - ptr);
ptr = offset + size;
continue;
}
-   ptr = map.m_la + map.m_llen;
+   memset(estart, 0, eend - ptr);
+   ptr = eend;
continue;
}
 
-   /* trim extent */
-   eend = min(offset + size, map.m_la + map.m_llen);
-   DBG_BUGON(ptr < map.m_la);
-
if (ptr > map.m_la) {
map.m_pa += ptr - map.m_la;
map.m_la = ptr;
}
 
-   ret = dev_read(buffer + ptr - offset,
-  map.m_pa, eend - map.m_la);
+   ret = dev_read(estart, map.m_pa, eend - map.m_la);
if (ret < 0)
return -EIO;
-
ptr = eend;
}
return 0;
@@ -138,6 

[PATCH 2/2] erofs-utils: more sanity check for buffer allocation optimization

2021-02-09 Thread Gao Xiang via Linux-erofs
From: Gao Xiang 

In case that new buffer allocation optimization logic is
potentially broken.

Signed-off-by: Gao Xiang 
---
 lib/cache.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/cache.c b/lib/cache.c
index e8840ac5dd31..c4851168ede7 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -186,8 +186,13 @@ static int erofs_bfind_for_attach(int type, erofs_off_t 
size,
   mapped_list);
 
/* last mapped block can be expended, don't handle it here */
-   if (cur == last_mapped_block)
+   if (list_next_entry(cur, list)->blkaddr == NULL_ADDR) {
+   DBG_BUGON(cur != last_mapped_block);
continue;
+   }
+
+   DBG_BUGON(cur->type != type);
+   DBG_BUGON(cur->blkaddr == NULL_ADDR);
 
ret = __erofs_battach(cur, NULL, size, alignsize,
  required_ext + inline_ext, true);
-- 
2.24.0



[PATCH 1/2] erofs-utils: don't reuse full mapped buffer blocks

2021-02-09 Thread Gao Xiang via Linux-erofs
From: Gao Xiang 

Otherwise it could cause data corruption since erofs_battach()
doesn't support full buffer blocks (and oob would be misjudged.)

Fixes: 185b0bcdef4b ("erofs-utils: optimize buffer allocation logic")
Signed-off-by: Gao Xiang 
---
 lib/cache.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/cache.c b/lib/cache.c
index 40d3b1f3f4d5..e8840ac5dd31 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -155,8 +155,8 @@ static int erofs_bfind_for_attach(int type, erofs_off_t 
size,
  struct erofs_buffer_block **bbp)
 {
struct erofs_buffer_block *cur, *bb;
-   unsigned int used0, usedmax, used;
-   int used_before, ret;
+   unsigned int used0, used_before, usedmax, used;
+   int ret;
 
used0 = (size + required_ext) % EROFS_BLKSIZ + inline_ext;
/* inline data should be in the same fs block */
@@ -177,7 +177,7 @@ static int erofs_bfind_for_attach(int type, erofs_off_t 
size,
 
used_before = rounddown(EROFS_BLKSIZ -
(size + required_ext + inline_ext), alignsize);
-   do {
+   for (; used_before; --used_before) {
struct list_head *bt = mapped_buckets[type] + used_before;
 
if (list_empty(bt))
@@ -203,7 +203,7 @@ static int erofs_bfind_for_attach(int type, erofs_off_t 
size,
bb = cur;
usedmax = used;
break;
-   } while (--used_before > 0);
+   }
 
 skip_mapped:
/* try to start from the last mapped one, which can be expended */
-- 
2.24.0



[PATCH] erofs: initialized fields can only be observed after bit is set

2021-02-09 Thread Gao Xiang via Linux-erofs
From: Gao Xiang 

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:  # 5.3+
Reported-by: Huang Jianan 
Signed-off-by: Gao Xiang 
---
 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, >flags))
+   if (test_bit(EROFS_I_EA_INITED_BIT, >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();
return 0;
+   }
 
if (wait_on_bit_lock(>flags, EROFS_I_BL_XATTR_BIT, TASK_KILLABLE))
return -ERESTARTSYS;
@@ -137,6 +143,8 @@ static int init_inode_xattrs(struct inode *inode)
}
xattr_iter_end(, atomic_map);
 
+   /* paired with smp_mb() at the beginning of the function. */
+   smp_mb();
set_bit(EROFS_I_EA_INITED_BIT, >flags);
 
 out_unlock:
diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
index ae325541884e..14d2de35110c 100644
--- a/fs/erofs/zmap.c
+++ b/fs/erofs/zmap.c
@@ -36,8 +36,14 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
void *kaddr;
struct z_erofs_map_header *h;
 
-   if (test_bit(EROFS_I_Z_INITED_BIT, >flags))
+   if (test_bit(EROFS_I_Z_INITED_BIT, >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();
return 0;
+   }
 
if (wait_on_bit_lock(>flags, EROFS_I_BL_Z_BIT, TASK_KILLABLE))
return -ERESTARTSYS;
@@ -83,6 +89,8 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
 
vi->z_physical_clusterbits[1] = vi->z_logical_clusterbits +
((h->h_clusterbits >> 5) & 7);
+   /* paired with smp_mb() at the beginning of the function */
+   smp_mb();
set_bit(EROFS_I_Z_INITED_BIT, >flags);
 unmap_done:
kunmap_atomic(kaddr);
-- 
2.24.0