aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-10-02 13:53:48 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-10-02 13:53:48 -0700
commit65aa35c93cc014c72bae944675ea6e88c47a5497 (patch)
treea0e6f4f82bb9fd4aea74704593ab29c755d7bb6a
parent3fd57e7a9e66b9a8bcbf0560ff09e84d0b8de1bd (diff)
parentdc76ea8c1087b5c44235566ed4be2202d21a8504 (diff)
downloadlinux-test-65aa35c93cc014c72bae944675ea6e88c47a5497.tar.gz
Merge tag 'erofs-for-5.4-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs
Pull erofs fixes from Gao Xiang: "Three patches to address regressions due to recent cleanups, mainly found by stress test on latest mainline kernel (no more regression out compared with older kernels for more than a week) One additional patch updates sub-entries in MAINTAINERS. Summary: - Fix error handling in erofs_read_superblock - Fix locking in erofs_get_meta_page - Fix inplace behavior due to decompression frontend cleanup - Update sub-entries in MAINTAINERS in order to better blame" * tag 'erofs-for-5.4-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs: erofs: fix mis-inplace determination related with noio chain erofs: fix erofs_get_meta_page locking due to a cleanup MAINTAINERS: erofs: complete sub-entries for erofs erofs: fix return value check in erofs_read_superblock()
-rw-r--r--MAINTAINERS3
-rw-r--r--fs/erofs/data.c10
-rw-r--r--fs/erofs/super.c4
-rw-r--r--fs/erofs/zdata.c12
4 files changed, 22 insertions, 7 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 296de2b51c832e..30a5b4028d2fc9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6112,7 +6112,10 @@ M: Gao Xiang <gaoxiang25@huawei.com>
M: Chao Yu <yuchao0@huawei.com>
L: linux-erofs@lists.ozlabs.org
S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
+F: Documentation/filesystems/erofs.txt
F: fs/erofs/
+F: include/trace/events/erofs.h
ERRSEQ ERROR TRACKING INFRASTRUCTURE
M: Jeff Layton <jlayton@kernel.org>
diff --git a/fs/erofs/data.c b/fs/erofs/data.c
index 8a9fcbd0e8ac19..fc3a8d8064f84f 100644
--- a/fs/erofs/data.c
+++ b/fs/erofs/data.c
@@ -34,11 +34,15 @@ static void erofs_readendio(struct bio *bio)
struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr)
{
- struct inode *const bd_inode = sb->s_bdev->bd_inode;
- struct address_space *const mapping = bd_inode->i_mapping;
+ struct address_space *const mapping = sb->s_bdev->bd_inode->i_mapping;
+ struct page *page;
- return read_cache_page_gfp(mapping, blkaddr,
+ page = read_cache_page_gfp(mapping, blkaddr,
mapping_gfp_constraint(mapping, ~__GFP_FS));
+ /* should already be PageUptodate */
+ if (!IS_ERR(page))
+ lock_page(page);
+ return page;
}
static int erofs_map_blocks_flatmode(struct inode *inode,
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index caf9a95173b0fb..0e369494f2f2c4 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -105,9 +105,9 @@ static int erofs_read_superblock(struct super_block *sb)
int ret;
page = read_mapping_page(sb->s_bdev->bd_inode->i_mapping, 0, NULL);
- if (!page) {
+ if (IS_ERR(page)) {
erofs_err(sb, "cannot read erofs superblock");
- return -EIO;
+ return PTR_ERR(page);
}
sbi = EROFS_SB(sb);
diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
index 96e34c90f81438..fad80c97d2476f 100644
--- a/fs/erofs/zdata.c
+++ b/fs/erofs/zdata.c
@@ -575,7 +575,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe,
struct erofs_map_blocks *const map = &fe->map;
struct z_erofs_collector *const clt = &fe->clt;
const loff_t offset = page_offset(page);
- bool tight = (clt->mode >= COLLECT_PRIMARY_HOOKED);
+ bool tight = true;
enum z_erofs_cache_alloctype cache_strategy;
enum z_erofs_page_type page_type;
@@ -628,8 +628,16 @@ restart_now:
preload_compressed_pages(clt, MNGD_MAPPING(sbi),
cache_strategy, pagepool);
- tight &= (clt->mode >= COLLECT_PRIMARY_HOOKED);
hitted:
+ /*
+ * Ensure the current partial page belongs to this submit chain rather
+ * than other concurrent submit chains or the noio(bypass) chain since
+ * those chains are handled asynchronously thus the page cannot be used
+ * for inplace I/O or pagevec (should be processed in strict order.)
+ */
+ tight &= (clt->mode >= COLLECT_PRIMARY_HOOKED &&
+ clt->mode != COLLECT_PRIMARY_FOLLOWED_NOINPLACE);
+
cur = end - min_t(unsigned int, offset + end - map->m_la, end);
if (!(map->m_flags & EROFS_MAP_MAPPED)) {
zero_user_segment(page, cur, end);