Merge tag 'erofs-for-5.4-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 2 Oct 2019 20:53:48 +0000 (13:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 2 Oct 2019 20:53:48 +0000 (13:53 -0700)
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()

MAINTAINERS
fs/erofs/data.c
fs/erofs/super.c
fs/erofs/zdata.c

index 296de2b51c832ecc1869a77624c964ce398a5236..30a5b4028d2fc9a4d5b0b8d872942db9d7692463 100644 (file)
@@ -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>
index 8a9fcbd0e8ac197fbe22d04c23fc66bb9feff7b8..fc3a8d8064f84f8ee1ce24787c2632ca17c09650 100644 (file)
@@ -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,
index caf9a95173b0fb8b4bb6f2c648564e8052b9ff5f..0e369494f2f2c43601e9d8b97c285258db1877aa 100644 (file)
@@ -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);
index 96e34c90f81438fc20493f96dfda98414608e462..fad80c97d2476fbeaff3858e7a10c0b4c6e583c6 100644 (file)
@@ -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);