aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/f2fs/checkpoint.c6
-rw-r--r--fs/f2fs/f2fs.h1
-rw-r--r--fs/f2fs/segment.c17
3 files changed, 22 insertions, 2 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 4aa521aa9bc3..890e23d208a8 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -762,6 +762,12 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
762 void *kaddr; 762 void *kaddr;
763 int i; 763 int i;
764 764
765 /*
766 * This avoids to conduct wrong roll-forward operations and uses
767 * metapages, so should be called prior to sync_meta_pages below.
768 */
769 discard_next_dnode(sbi);
770
765 /* Flush all the NAT/SIT pages */ 771 /* Flush all the NAT/SIT pages */
766 while (get_pages(sbi, F2FS_DIRTY_META)) 772 while (get_pages(sbi, F2FS_DIRTY_META))
767 sync_meta_pages(sbi, META, LONG_MAX); 773 sync_meta_pages(sbi, META, LONG_MAX);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 2ecac8312359..2c5a5dadae65 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1179,6 +1179,7 @@ int f2fs_issue_flush(struct f2fs_sb_info *);
1179void invalidate_blocks(struct f2fs_sb_info *, block_t); 1179void invalidate_blocks(struct f2fs_sb_info *, block_t);
1180void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t); 1180void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t);
1181void clear_prefree_segments(struct f2fs_sb_info *); 1181void clear_prefree_segments(struct f2fs_sb_info *);
1182void discard_next_dnode(struct f2fs_sb_info *);
1182int npages_for_summary_flush(struct f2fs_sb_info *); 1183int npages_for_summary_flush(struct f2fs_sb_info *);
1183void allocate_new_segments(struct f2fs_sb_info *); 1184void allocate_new_segments(struct f2fs_sb_info *);
1184struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); 1185struct page *get_sum_page(struct f2fs_sb_info *, unsigned int);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 1e264e761f71..9993f94848fc 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -335,13 +335,26 @@ static void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno)
335 mutex_unlock(&dirty_i->seglist_lock); 335 mutex_unlock(&dirty_i->seglist_lock);
336} 336}
337 337
338static void f2fs_issue_discard(struct f2fs_sb_info *sbi, 338static int f2fs_issue_discard(struct f2fs_sb_info *sbi,
339 block_t blkstart, block_t blklen) 339 block_t blkstart, block_t blklen)
340{ 340{
341 sector_t start = SECTOR_FROM_BLOCK(sbi, blkstart); 341 sector_t start = SECTOR_FROM_BLOCK(sbi, blkstart);
342 sector_t len = SECTOR_FROM_BLOCK(sbi, blklen); 342 sector_t len = SECTOR_FROM_BLOCK(sbi, blklen);
343 blkdev_issue_discard(sbi->sb->s_bdev, start, len, GFP_NOFS, 0);
344 trace_f2fs_issue_discard(sbi->sb, blkstart, blklen); 343 trace_f2fs_issue_discard(sbi->sb, blkstart, blklen);
344 return blkdev_issue_discard(sbi->sb->s_bdev, start, len, GFP_NOFS, 0);
345}
346
347void discard_next_dnode(struct f2fs_sb_info *sbi)
348{
349 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
350 block_t blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
351
352 if (f2fs_issue_discard(sbi, blkaddr, 1)) {
353 struct page *page = grab_meta_page(sbi, blkaddr);
354 /* zero-filled page */
355 set_page_dirty(page);
356 f2fs_put_page(page, 1);
357 }
345} 358}
346 359
347static void add_discard_addrs(struct f2fs_sb_info *sbi, 360static void add_discard_addrs(struct f2fs_sb_info *sbi,