Loading fs/f2fs/data.c +10 −8 Original line number Diff line number Diff line Loading @@ -587,9 +587,6 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, ctx->bio = bio; ctx->enabled_steps = post_read_steps; bio->bi_private = ctx; /* wait the page to be moved by cleaning */ f2fs_wait_on_block_writeback(sbi, blkaddr); } return bio; Loading @@ -607,6 +604,9 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page, if (f2fs_may_encrypt_bio(inode, NULL)) fscrypt_set_ice_dun(inode, bio, PG_DUN(inode, page)); /* wait for GCed page writeback via META_MAPPING */ f2fs_wait_on_block_writeback(inode, blkaddr); if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { bio_put(bio); return -EFAULT; Loading Loading @@ -1562,6 +1562,12 @@ static int f2fs_mpage_readpages(struct address_space *mapping, if (bio_encrypted) fscrypt_set_ice_dun(inode, bio, dun); } /* * If the page is under writeback, we need to wait for * its completion to see the correct decrypted data. */ f2fs_wait_on_block_writeback(inode, block_nr); if (bio_add_page(bio, page, blocksize, 0) < blocksize) goto submit_and_realloc; Loading Loading @@ -1628,7 +1634,7 @@ static int encrypt_one_page(struct f2fs_io_info *fio) return 0; /* wait for GCed page writeback via META_MAPPING */ f2fs_wait_on_block_writeback(fio->sbi, fio->old_blkaddr); f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); retry_encrypt: if (fscrypt_using_hardware_encryption(inode)) Loading Loading @@ -2371,10 +2377,6 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, f2fs_wait_on_page_writeback(page, DATA, false); /* wait for GCed page writeback via META_MAPPING */ if (f2fs_post_read_required(inode)) f2fs_wait_on_block_writeback(sbi, blkaddr); if (len == PAGE_SIZE || PageUptodate(page)) return 0; Loading fs/f2fs/f2fs.h +2 −2 Original line number Diff line number Diff line Loading @@ -2733,7 +2733,7 @@ struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs); void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid); struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid); struct page *get_node_page_ra(struct page *parent, int start); void move_node_page(struct page *node_page, int gc_type); int move_node_page(struct page *node_page, int gc_type); int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, struct writeback_control *wbc, bool atomic); int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc, Loading Loading @@ -2800,7 +2800,7 @@ void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, struct f2fs_io_info *fio, bool add_list); void f2fs_wait_on_page_writeback(struct page *page, enum page_type type, bool ordered); void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr); void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr); void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk); void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk); int lookup_journal_in_cursum(struct f2fs_journal *journal, int type, Loading fs/f2fs/file.c +1 −2 Original line number Diff line number Diff line Loading @@ -111,8 +111,7 @@ static int f2fs_vm_page_mkwrite(struct vm_fault *vmf) f2fs_wait_on_page_writeback(page, DATA, false); /* wait for GCed page writeback via META_MAPPING */ if (f2fs_post_read_required(inode)) f2fs_wait_on_block_writeback(sbi, dn.data_blkaddr); f2fs_wait_on_block_writeback(inode, dn.data_blkaddr); out_sem: up_read(&F2FS_I(inode)->i_mmap_sem); Loading fs/f2fs/gc.c +52 −22 Original line number Diff line number Diff line Loading @@ -477,13 +477,14 @@ static int check_valid_map(struct f2fs_sb_info *sbi, * On validity, copy that node with cold status, otherwise (invalid node) * ignore that. */ static void gc_node_segment(struct f2fs_sb_info *sbi, static int gc_node_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, unsigned int segno, int gc_type) { struct f2fs_summary *entry; block_t start_addr; int off; int phase = 0; int submitted = 0; start_addr = START_BLOCK(sbi, segno); Loading @@ -494,10 +495,11 @@ static void gc_node_segment(struct f2fs_sb_info *sbi, nid_t nid = le32_to_cpu(entry->nid); struct page *node_page; struct node_info ni; int err; /* stop BG_GC if there is not enough free sections. */ if (gc_type == BG_GC && has_not_enough_free_secs(sbi, 0, 0)) return; return submitted; if (check_valid_map(sbi, segno, off) == 0) continue; Loading Loading @@ -530,12 +532,15 @@ static void gc_node_segment(struct f2fs_sb_info *sbi, continue; } move_node_page(node_page, gc_type); err = move_node_page(node_page, gc_type); if (!err && gc_type == FG_GC) submitted++; stat_inc_node_blk_count(sbi, 1, gc_type); } if (++phase < 3) goto next_step; return submitted; } /* Loading Loading @@ -602,7 +607,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, * Move data block via META_MAPPING while keeping locked data page. * This can be used to move blocks, aka LBAs, directly on disk. */ static void move_data_block(struct inode *inode, block_t bidx, static int move_data_block(struct inode *inode, block_t bidx, unsigned int segno, int off) { struct f2fs_io_info fio = { Loading @@ -620,21 +625,26 @@ static void move_data_block(struct inode *inode, block_t bidx, struct node_info ni; struct page *page; block_t newaddr; int err; int err = 0; /* do not read out */ page = f2fs_grab_cache_page(inode->i_mapping, bidx, false); if (!page) return; return -ENOMEM; if (!check_valid_map(F2FS_I_SB(inode), segno, off)) if (!check_valid_map(F2FS_I_SB(inode), segno, off)) { err = -ENOENT; goto out; } if (f2fs_is_atomic_file(inode)) if (f2fs_is_atomic_file(inode)) { err = -EAGAIN; goto out; } if (f2fs_is_pinned_file(inode)) { f2fs_pin_file_control(inode, true); err = -EAGAIN; goto out; } Loading @@ -645,6 +655,7 @@ static void move_data_block(struct inode *inode, block_t bidx, if (unlikely(dn.data_blkaddr == NULL_ADDR)) { ClearPageUptodate(page); err = -ENOENT; goto put_out; } Loading Loading @@ -724,31 +735,40 @@ static void move_data_block(struct inode *inode, block_t bidx, f2fs_put_dnode(&dn); out: f2fs_put_page(page, 1); return err; } static void move_data_page(struct inode *inode, block_t bidx, int gc_type, static int move_data_page(struct inode *inode, block_t bidx, int gc_type, unsigned int segno, int off) { struct page *page; int err = 0; page = get_lock_data_page(inode, bidx, true); if (IS_ERR(page)) return; return PTR_ERR(page); if (!check_valid_map(F2FS_I_SB(inode), segno, off)) if (!check_valid_map(F2FS_I_SB(inode), segno, off)) { err = -ENOENT; goto out; } if (f2fs_is_atomic_file(inode)) if (f2fs_is_atomic_file(inode)) { err = -EAGAIN; goto out; } if (f2fs_is_pinned_file(inode)) { if (gc_type == FG_GC) f2fs_pin_file_control(inode, true); err = -EAGAIN; goto out; } if (gc_type == BG_GC) { if (PageWriteback(page)) if (PageWriteback(page)) { err = -EAGAIN; goto out; } set_page_dirty(page); set_cold_data(page); } else { Loading @@ -766,7 +786,6 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, .io_type = FS_GC_DATA_IO, }; bool is_dirty = PageDirty(page); int err; retry: set_page_dirty(page); Loading @@ -791,6 +810,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, } out: f2fs_put_page(page, 1); return err; } /* Loading @@ -800,7 +820,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, * If the parent node is not valid or the data block address is different, * the victim data block is ignored. */ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, struct gc_inode_list *gc_list, unsigned int segno, int gc_type) { struct super_block *sb = sbi->sb; Loading @@ -808,6 +828,7 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, block_t start_addr; int off; int phase = 0; int submitted = 0; start_addr = START_BLOCK(sbi, segno); Loading @@ -824,7 +845,7 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, /* stop BG_GC if there is not enough free sections. */ if (gc_type == BG_GC && has_not_enough_free_secs(sbi, 0, 0)) return; return submitted; if (check_valid_map(sbi, segno, off) == 0) continue; Loading Loading @@ -888,6 +909,7 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (inode) { struct f2fs_inode_info *fi = F2FS_I(inode); bool locked = false; int err; if (S_ISREG(inode->i_mode)) { if (!down_write_trylock(&fi->dio_rwsem[READ])) Loading @@ -906,11 +928,15 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, start_bidx = start_bidx_of_node(nofs, inode) + ofs_in_node; if (f2fs_post_read_required(inode)) move_data_block(inode, start_bidx, segno, off); err = move_data_block(inode, start_bidx, segno, off); else move_data_page(inode, start_bidx, gc_type, err = move_data_page(inode, start_bidx, gc_type, segno, off); if (!err && (gc_type == FG_GC || f2fs_post_read_required(inode))) submitted++; if (locked) { up_write(&fi->dio_rwsem[WRITE]); up_write(&fi->dio_rwsem[READ]); Loading @@ -922,6 +948,8 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (++phase < 5) goto next_step; return submitted; } static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim, Loading Loading @@ -949,6 +977,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, int seg_freed = 0; unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ? SUM_TYPE_DATA : SUM_TYPE_NODE; int submitted = 0; /* readahead multi ssa blocks those have contiguous address */ if (sbi->segs_per_sec > 1) Loading Loading @@ -992,10 +1021,11 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, * - lock_page(sum_page) */ if (type == SUM_TYPE_NODE) gc_node_segment(sbi, sum->entries, segno, gc_type); else gc_data_segment(sbi, sum->entries, gc_list, segno, submitted += gc_node_segment(sbi, sum->entries, segno, gc_type); else submitted += gc_data_segment(sbi, sum->entries, gc_list, segno, gc_type); stat_inc_seg_count(sbi, type, gc_type); Loading @@ -1006,7 +1036,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, f2fs_put_page(sum_page, 0); } if (gc_type == FG_GC) if (submitted) f2fs_submit_merged_write(sbi, (type == SUM_TYPE_NODE) ? NODE : DATA); Loading fs/f2fs/node.c +10 −3 Original line number Diff line number Diff line Loading @@ -1446,8 +1446,10 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, return AOP_WRITEPAGE_ACTIVATE; } void move_node_page(struct page *node_page, int gc_type) int move_node_page(struct page *node_page, int gc_type) { int err = 0; if (gc_type == FG_GC) { struct writeback_control wbc = { .sync_mode = WB_SYNC_ALL, Loading @@ -1459,12 +1461,16 @@ void move_node_page(struct page *node_page, int gc_type) f2fs_wait_on_page_writeback(node_page, NODE, true); f2fs_bug_on(F2FS_P_SB(node_page), PageWriteback(node_page)); if (!clear_page_dirty_for_io(node_page)) if (!clear_page_dirty_for_io(node_page)) { err = -EAGAIN; goto out_page; } if (__write_node_page(node_page, false, NULL, &wbc, false, FS_GC_NODE_IO)) &wbc, false, FS_GC_NODE_IO)) { err = -EAGAIN; unlock_page(node_page); } goto release_page; } else { /* set page dirty and write it */ Loading @@ -1475,6 +1481,7 @@ void move_node_page(struct page *node_page, int gc_type) unlock_page(node_page); release_page: f2fs_put_page(node_page, 0); return err; } static int f2fs_write_node_page(struct page *page, Loading Loading
fs/f2fs/data.c +10 −8 Original line number Diff line number Diff line Loading @@ -587,9 +587,6 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, ctx->bio = bio; ctx->enabled_steps = post_read_steps; bio->bi_private = ctx; /* wait the page to be moved by cleaning */ f2fs_wait_on_block_writeback(sbi, blkaddr); } return bio; Loading @@ -607,6 +604,9 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page, if (f2fs_may_encrypt_bio(inode, NULL)) fscrypt_set_ice_dun(inode, bio, PG_DUN(inode, page)); /* wait for GCed page writeback via META_MAPPING */ f2fs_wait_on_block_writeback(inode, blkaddr); if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { bio_put(bio); return -EFAULT; Loading Loading @@ -1562,6 +1562,12 @@ static int f2fs_mpage_readpages(struct address_space *mapping, if (bio_encrypted) fscrypt_set_ice_dun(inode, bio, dun); } /* * If the page is under writeback, we need to wait for * its completion to see the correct decrypted data. */ f2fs_wait_on_block_writeback(inode, block_nr); if (bio_add_page(bio, page, blocksize, 0) < blocksize) goto submit_and_realloc; Loading Loading @@ -1628,7 +1634,7 @@ static int encrypt_one_page(struct f2fs_io_info *fio) return 0; /* wait for GCed page writeback via META_MAPPING */ f2fs_wait_on_block_writeback(fio->sbi, fio->old_blkaddr); f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); retry_encrypt: if (fscrypt_using_hardware_encryption(inode)) Loading Loading @@ -2371,10 +2377,6 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, f2fs_wait_on_page_writeback(page, DATA, false); /* wait for GCed page writeback via META_MAPPING */ if (f2fs_post_read_required(inode)) f2fs_wait_on_block_writeback(sbi, blkaddr); if (len == PAGE_SIZE || PageUptodate(page)) return 0; Loading
fs/f2fs/f2fs.h +2 −2 Original line number Diff line number Diff line Loading @@ -2733,7 +2733,7 @@ struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs); void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid); struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid); struct page *get_node_page_ra(struct page *parent, int start); void move_node_page(struct page *node_page, int gc_type); int move_node_page(struct page *node_page, int gc_type); int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, struct writeback_control *wbc, bool atomic); int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc, Loading Loading @@ -2800,7 +2800,7 @@ void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, struct f2fs_io_info *fio, bool add_list); void f2fs_wait_on_page_writeback(struct page *page, enum page_type type, bool ordered); void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr); void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr); void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk); void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk); int lookup_journal_in_cursum(struct f2fs_journal *journal, int type, Loading
fs/f2fs/file.c +1 −2 Original line number Diff line number Diff line Loading @@ -111,8 +111,7 @@ static int f2fs_vm_page_mkwrite(struct vm_fault *vmf) f2fs_wait_on_page_writeback(page, DATA, false); /* wait for GCed page writeback via META_MAPPING */ if (f2fs_post_read_required(inode)) f2fs_wait_on_block_writeback(sbi, dn.data_blkaddr); f2fs_wait_on_block_writeback(inode, dn.data_blkaddr); out_sem: up_read(&F2FS_I(inode)->i_mmap_sem); Loading
fs/f2fs/gc.c +52 −22 Original line number Diff line number Diff line Loading @@ -477,13 +477,14 @@ static int check_valid_map(struct f2fs_sb_info *sbi, * On validity, copy that node with cold status, otherwise (invalid node) * ignore that. */ static void gc_node_segment(struct f2fs_sb_info *sbi, static int gc_node_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, unsigned int segno, int gc_type) { struct f2fs_summary *entry; block_t start_addr; int off; int phase = 0; int submitted = 0; start_addr = START_BLOCK(sbi, segno); Loading @@ -494,10 +495,11 @@ static void gc_node_segment(struct f2fs_sb_info *sbi, nid_t nid = le32_to_cpu(entry->nid); struct page *node_page; struct node_info ni; int err; /* stop BG_GC if there is not enough free sections. */ if (gc_type == BG_GC && has_not_enough_free_secs(sbi, 0, 0)) return; return submitted; if (check_valid_map(sbi, segno, off) == 0) continue; Loading Loading @@ -530,12 +532,15 @@ static void gc_node_segment(struct f2fs_sb_info *sbi, continue; } move_node_page(node_page, gc_type); err = move_node_page(node_page, gc_type); if (!err && gc_type == FG_GC) submitted++; stat_inc_node_blk_count(sbi, 1, gc_type); } if (++phase < 3) goto next_step; return submitted; } /* Loading Loading @@ -602,7 +607,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, * Move data block via META_MAPPING while keeping locked data page. * This can be used to move blocks, aka LBAs, directly on disk. */ static void move_data_block(struct inode *inode, block_t bidx, static int move_data_block(struct inode *inode, block_t bidx, unsigned int segno, int off) { struct f2fs_io_info fio = { Loading @@ -620,21 +625,26 @@ static void move_data_block(struct inode *inode, block_t bidx, struct node_info ni; struct page *page; block_t newaddr; int err; int err = 0; /* do not read out */ page = f2fs_grab_cache_page(inode->i_mapping, bidx, false); if (!page) return; return -ENOMEM; if (!check_valid_map(F2FS_I_SB(inode), segno, off)) if (!check_valid_map(F2FS_I_SB(inode), segno, off)) { err = -ENOENT; goto out; } if (f2fs_is_atomic_file(inode)) if (f2fs_is_atomic_file(inode)) { err = -EAGAIN; goto out; } if (f2fs_is_pinned_file(inode)) { f2fs_pin_file_control(inode, true); err = -EAGAIN; goto out; } Loading @@ -645,6 +655,7 @@ static void move_data_block(struct inode *inode, block_t bidx, if (unlikely(dn.data_blkaddr == NULL_ADDR)) { ClearPageUptodate(page); err = -ENOENT; goto put_out; } Loading Loading @@ -724,31 +735,40 @@ static void move_data_block(struct inode *inode, block_t bidx, f2fs_put_dnode(&dn); out: f2fs_put_page(page, 1); return err; } static void move_data_page(struct inode *inode, block_t bidx, int gc_type, static int move_data_page(struct inode *inode, block_t bidx, int gc_type, unsigned int segno, int off) { struct page *page; int err = 0; page = get_lock_data_page(inode, bidx, true); if (IS_ERR(page)) return; return PTR_ERR(page); if (!check_valid_map(F2FS_I_SB(inode), segno, off)) if (!check_valid_map(F2FS_I_SB(inode), segno, off)) { err = -ENOENT; goto out; } if (f2fs_is_atomic_file(inode)) if (f2fs_is_atomic_file(inode)) { err = -EAGAIN; goto out; } if (f2fs_is_pinned_file(inode)) { if (gc_type == FG_GC) f2fs_pin_file_control(inode, true); err = -EAGAIN; goto out; } if (gc_type == BG_GC) { if (PageWriteback(page)) if (PageWriteback(page)) { err = -EAGAIN; goto out; } set_page_dirty(page); set_cold_data(page); } else { Loading @@ -766,7 +786,6 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, .io_type = FS_GC_DATA_IO, }; bool is_dirty = PageDirty(page); int err; retry: set_page_dirty(page); Loading @@ -791,6 +810,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, } out: f2fs_put_page(page, 1); return err; } /* Loading @@ -800,7 +820,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type, * If the parent node is not valid or the data block address is different, * the victim data block is ignored. */ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, struct gc_inode_list *gc_list, unsigned int segno, int gc_type) { struct super_block *sb = sbi->sb; Loading @@ -808,6 +828,7 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, block_t start_addr; int off; int phase = 0; int submitted = 0; start_addr = START_BLOCK(sbi, segno); Loading @@ -824,7 +845,7 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, /* stop BG_GC if there is not enough free sections. */ if (gc_type == BG_GC && has_not_enough_free_secs(sbi, 0, 0)) return; return submitted; if (check_valid_map(sbi, segno, off) == 0) continue; Loading Loading @@ -888,6 +909,7 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (inode) { struct f2fs_inode_info *fi = F2FS_I(inode); bool locked = false; int err; if (S_ISREG(inode->i_mode)) { if (!down_write_trylock(&fi->dio_rwsem[READ])) Loading @@ -906,11 +928,15 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, start_bidx = start_bidx_of_node(nofs, inode) + ofs_in_node; if (f2fs_post_read_required(inode)) move_data_block(inode, start_bidx, segno, off); err = move_data_block(inode, start_bidx, segno, off); else move_data_page(inode, start_bidx, gc_type, err = move_data_page(inode, start_bidx, gc_type, segno, off); if (!err && (gc_type == FG_GC || f2fs_post_read_required(inode))) submitted++; if (locked) { up_write(&fi->dio_rwsem[WRITE]); up_write(&fi->dio_rwsem[READ]); Loading @@ -922,6 +948,8 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (++phase < 5) goto next_step; return submitted; } static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim, Loading Loading @@ -949,6 +977,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, int seg_freed = 0; unsigned char type = IS_DATASEG(get_seg_entry(sbi, segno)->type) ? SUM_TYPE_DATA : SUM_TYPE_NODE; int submitted = 0; /* readahead multi ssa blocks those have contiguous address */ if (sbi->segs_per_sec > 1) Loading Loading @@ -992,10 +1021,11 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, * - lock_page(sum_page) */ if (type == SUM_TYPE_NODE) gc_node_segment(sbi, sum->entries, segno, gc_type); else gc_data_segment(sbi, sum->entries, gc_list, segno, submitted += gc_node_segment(sbi, sum->entries, segno, gc_type); else submitted += gc_data_segment(sbi, sum->entries, gc_list, segno, gc_type); stat_inc_seg_count(sbi, type, gc_type); Loading @@ -1006,7 +1036,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, f2fs_put_page(sum_page, 0); } if (gc_type == FG_GC) if (submitted) f2fs_submit_merged_write(sbi, (type == SUM_TYPE_NODE) ? NODE : DATA); Loading
fs/f2fs/node.c +10 −3 Original line number Diff line number Diff line Loading @@ -1446,8 +1446,10 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, return AOP_WRITEPAGE_ACTIVATE; } void move_node_page(struct page *node_page, int gc_type) int move_node_page(struct page *node_page, int gc_type) { int err = 0; if (gc_type == FG_GC) { struct writeback_control wbc = { .sync_mode = WB_SYNC_ALL, Loading @@ -1459,12 +1461,16 @@ void move_node_page(struct page *node_page, int gc_type) f2fs_wait_on_page_writeback(node_page, NODE, true); f2fs_bug_on(F2FS_P_SB(node_page), PageWriteback(node_page)); if (!clear_page_dirty_for_io(node_page)) if (!clear_page_dirty_for_io(node_page)) { err = -EAGAIN; goto out_page; } if (__write_node_page(node_page, false, NULL, &wbc, false, FS_GC_NODE_IO)) &wbc, false, FS_GC_NODE_IO)) { err = -EAGAIN; unlock_page(node_page); } goto release_page; } else { /* set page dirty and write it */ Loading @@ -1475,6 +1481,7 @@ void move_node_page(struct page *node_page, int gc_type) unlock_page(node_page); release_page: f2fs_put_page(node_page, 0); return err; } static int f2fs_write_node_page(struct page *page, Loading