f2fs: invalidate meta pages only for post_read required inode
authorChao Yu <chao@kernel.org>
Tue, 12 Jul 2022 15:26:43 +0000 (23:26 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Sun, 31 Jul 2022 03:17:06 +0000 (20:17 -0700)
After commit e3b49ea36802 ("f2fs: invalidate META_MAPPING before
IPU/DIO write"), invalidate_mapping_pages() will be called to
avoid race condition in between IPU/DIO and readahead for GC.

However, readahead flow is only used for post_read required inode,
so this patch adds check condition to avoids unnecessary page cache
invalidating for non-post_read inode.

Signed-off-by: Chao Yu <chao.yu@oppo.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/segment.c

index f2a272613477919cae884be0c3ca2500a2c72003..de140afc42c1cf9856999c4b0acf6e242b5d3b7e 100644 (file)
@@ -1463,12 +1463,9 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
                        *map->m_next_extent = pgofs + map->m_len;
 
                /* for hardware encryption, but to avoid potential issue in future */
-               if (flag == F2FS_GET_BLOCK_DIO) {
+               if (flag == F2FS_GET_BLOCK_DIO)
                        f2fs_wait_on_block_writeback_range(inode,
                                                map->m_pblk, map->m_len);
-                       invalidate_mapping_pages(META_MAPPING(sbi),
-                               map->m_pblk, map->m_pblk + map->m_len - 1);
-               }
 
                if (map->m_multidev_dio) {
                        block_t blk_addr = map->m_pblk;
@@ -1684,8 +1681,6 @@ sync_out:
                 */
                f2fs_wait_on_block_writeback_range(inode,
                                                map->m_pblk, map->m_len);
-               invalidate_mapping_pages(META_MAPPING(sbi),
-                               map->m_pblk, map->m_pblk + map->m_len - 1);
 
                if (map->m_multidev_dio) {
                        block_t blk_addr = map->m_pblk;
@@ -2733,6 +2728,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
                .submitted = false,
                .compr_blocks = compr_blocks,
                .need_lock = LOCK_RETRY,
+               .post_read = f2fs_post_read_required(inode),
                .io_type = io_type,
                .io_wbc = wbc,
                .bio = bio,
index 116d491b346d47ff5b7956ad7f796078a2d0e08a..d0f428aef34bab7cb51a08db08b0bc5e35565cc7 100644 (file)
@@ -1199,6 +1199,7 @@ struct f2fs_io_info {
        bool retry;             /* need to reallocate block address */
        int compr_blocks;       /* # of compressed block addresses */
        bool encrypted;         /* indicate file is encrypted */
+       bool post_read;         /* require post read */
        enum iostat_type io_type;       /* io type */
        struct writeback_control *io_wbc; /* writeback control */
        struct bio **bio;               /* bio for ipu */
index ce571c0d712696360128772382108cb5d6298ff7..12b0edc48f7b251dfa4f035fc807ef33556aad54 100644 (file)
@@ -3433,7 +3433,8 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio)
                goto drop_bio;
        }
 
-       invalidate_mapping_pages(META_MAPPING(sbi),
+       if (fio->post_read)
+               invalidate_mapping_pages(META_MAPPING(sbi),
                                fio->new_blkaddr, fio->new_blkaddr);
 
        stat_inc_inplace_blocks(fio->sbi);
@@ -3616,10 +3617,16 @@ void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr)
 void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr,
                                                                block_t len)
 {
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        block_t i;
 
+       if (!f2fs_post_read_required(inode))
+               return;
+
        for (i = 0; i < len; i++)
                f2fs_wait_on_block_writeback(inode, blkaddr + i);
+
+       invalidate_mapping_pages(META_MAPPING(sbi), blkaddr, blkaddr + len - 1);
 }
 
 static int read_compacted_summaries(struct f2fs_sb_info *sbi)