[xiang-erofs:dev-test] BUILD SUCCESS 0e9a3c4fae5498e86dd11985143c4858a8300705
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
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
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
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
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